【问题标题】:How can I match against multiple regexes in Perl?如何匹配 Perl 中的多个正则表达式?
【发布时间】:2011-08-30 07:32:29
【问题描述】:

我看过这篇关于匹配多个正则表达式的帖子 How can I match against multiple regexes in Perl?

我正在寻找将数组中包含的所有值与一个非常大的文件 (500 MB) 进行匹配的最快方法。

模式是从标准输入读取的,并且可能包含必须在正则表达式中使用的特殊字符(锚点、字符类等)。当所有模式都包含在当前行中时,匹配必须发生。

目前我正在使用嵌套的for循环,但我对速度不是很满意......

感谢您的建议。

【问题讨论】:

  • 您如何确认 500MB 数据的 IO 速度不是限制因素?
  • 作为一个简单的优化,请确保首先测试最有可能失败的正则表达式。这样,您可以在发现故障时尽快跳到下一条记录。
  • 也许您应该向我们展示一些代码和正则表达式,以便我们可以使用一些东西。此外,有关输入外观的任何信息。
  • 文件被读取然后加载到一个数组中以便更快的访问,所以我认为它不是瓶颈。
  • @user764169 你把 500 megs 拉进内存?假设您逐行搜索并且每个文件只执行一次,这会浪费大量内存,并且不会影响搜索性能。事实上,当 Perl 分配所有内存时,它可能会减慢速度。

标签: regex perl


【解决方案1】:

按照您链接到的帖子中的建议尝试Regexp::Assemble,并将其与grep 等迭代方法进行比较。 Regexp::Assemble 应该产生最快的解决方案,因为 Perl 可以优化连接的正则表达式,而不是为每个正则表达式扫描整行。由于您事先不知道您的输入,ymmv。

您使用的 Perl 版本会影响性能。 5.10 正是为此目的引入了许多优化(参见“tries”)。最大的用例之一是像 SpamAssassin 这样的垃圾邮件扫描器,它为他们扫描的所有模式构建一个大的正则表达式,就像 Regexp::Assemble 一样。

最后,由于您的输入非常大,可能值得将正则表达式组装到一个文件中,然后运行grep -P -f $regex_file $big_file-P 告诉 grep 使用 Perl 兼容的正则表达式。该文件用于避免 shell 引用或命令大小限制。 grep 可能会关闭 Perl。

最后,您将不得不进行基准测试。

【讨论】:

  • Regexp::Assemble 的问题是当它匹配一个条件时返回“成功”,我需要匹配所有条件。我认为继续使用嵌套的“for”循环会更快。我正在使用 perl 5.14(通过出色的 perlbrew)。
【解决方案2】:

您尝试过使用 grep 吗?

while($line=<>) {
    if (scalar(grep($line=~/$_/,@regexps))==scalar(@regexps)) {
       # ... All matched
    }
}

【讨论】:

  • 或者干脆if (!grep { !condition } @list) {...}
  • 感谢此代码很简单,似乎可以使用 5.014;我的@regexps= qw(foo?bar{2} [Rr]at ^this barren$); my $line='这食物比较贫瘠'; if (scalar(grep($line=~/$_/,@regexps))==scalar(@regexps)) { 说'所有匹配'; }
    else {说'不是全部匹配'}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多