【问题标题】:is any of array items contained in a string是字符串中包含的任何数组项
【发布时间】:2013-05-19 20:20:08
【问题描述】:

我有一个关键字列表和一个黑名单。 我想删除所有包含任何黑名单项的关键字。 目前我这样做:

my @keywords = ( 'some good keyword', 'some other good keyword', 'some bad keyword');
my @blacklist = ( 'bad' );

A: for my $keyword ( @keywords ) {
    B: for my $bl ( @blacklist ) {
        next A if $keyword =~ /$bl/i;      # omitting $keyword
    }
    # some keyword cleaning (for instance: erasing non a-zA-Z0-9 characters, etc)
}

我想知道有什么最快的方法可以做到这一点,因为目前我有大约 2500 万个关键字和数百个单词在黑名单中。

【问题讨论】:

  • 你想要一个带有过滤@keywords的新数组吗?
  • 可以是新数组。

标签: arrays string perl contain


【解决方案1】:

应该这样做:

my @indices;
for my $i (0..$#keywords) {
  for my $bl (@blacklist) {
    if ($keywords[$i] =~ $bl) {
      push(@indices, $i);
      last;
    }
  }
}
for my $i (@indices) {
  @keywords = splice(@keywords, $i);
}

【讨论】:

    【解决方案2】:

    如果您想保留嵌套循环,预编译搜索可能会有所帮助 my @blacklist = ( qr/bad/i )

    或者,从my @blacklist = ( 'bad', 'awful', 'worst' ) 更改为my $blacklist = qr/bad|awful|worst/;,然后将内部循环替换为if ( $keywords[$i] =~ $blacklist ) ...

    【讨论】:

      【解决方案3】:

      最直接的选择是将join 黑名单条目放入单个正则表达式,然后将grep 关键字列表用于那些不匹配该正则表达式的关键字:

      #!/usr/bin/env perl    
      
      use strict;
      use warnings;
      use 5.010;
      
      my @keywords = 
        ('some good keyword', 'some other good keyword', 'some bad keyword');
      my @blacklist = ('bad');
      
      my $re = join '|', @blacklist;
      my @good = grep { $_ !~ /$re/ } @keywords;
      
      say join "\n", @good;
      

      输出:

      some good keyword
      some other good keyword
      

      【讨论】:

      • 非常感谢!对于 50k 关键字的测试,执行时间从 34 秒下降到 0.6 秒
      • metacpan.org/module/Regexp::Assemble - Regexp::Assemble 进一步提高了性能。
      • 演示:perl -MData::Printer -MRegexp::Assemble -E "my $ra = Regexp::Assemble->new(); for my $word (qw/apple asp application aspire应用土豚蛇/) { $ra->add($word) } p($ra->re);"给出 (?:a(?:ppl(?:icat(?:ion|e)|e)|sp(?:ire)?|ardvark)|snake)
      猜你喜欢
      • 2015-09-08
      • 2012-02-18
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      • 2020-12-01
      • 2011-01-08
      相关资源
      最近更新 更多