3

我正在编写一个日志解析器,它逐行读取日志,我有大约 100 条规则,它的工作方式如下:

if ($line =~ /blabla (field1) (field2)/) 
{ do something } 
else if ($line =~ /something (field1) (field2) else/)
{ do something }

但是对于一个大日志文件,将一行与这么多规则匹配可能会很慢,它会是O(n).

那么,对这个问题有什么建议吗?由于它不仅仅是纯字符串和通配符匹配,我不知道是否有任何我可以使用的数据结构。

4

4 回答 4

7

也许可以使用调度表?

my %handlers = (
   blabla    => \&blabla,
   something => \&something,
);

while (<>) {
   my ($keyword) = $line =~ /^(\S+)/
      or next;

   $handlers{$keyword}
      or next;

   $handlers{$keyword}->($line);
}
于 2012-11-22T06:20:46.193 回答
5

我相信你的优化还为时过早。

您是否尝试过使用这个名义上的大日志文件?真的是太慢了吗?然后,如果它确实太慢,请使用像 Devel::NYTProf 这样的分析工具来找出到底是什么慢了。

于 2012-11-22T04:28:48.550 回答
1

您可以使用Regexp::Assemble将多个正则表达式组合成一个以加快匹配速度

以下是来自模块的描述

Regexp::Assemble 采用任意数量的正则表达式并将它们组合成一个正则表达式(或 RE),该正则表达式匹配所有单个 RE 匹配的内容。

因此,无需循环使用大量表达式列表,只需针对一个表达式测试目标字符串即可。当您有数千种模式要处理时,这很有趣。努力生产尽可能小的图案。

还可以跟踪原始模式,以便您可以确定在形成组合模式的源模式中,哪个是导致匹配发生的模式。

于 2012-11-22T09:54:29.373 回答
1

我建议您重新设计日志解析器。可能是我错了,但我认为您尝试匹配日志文件中可能发生的所有情况。

尝试使用词法和句法分析器。抱歉,我不知道 Perl 上的好示例,但类似​​Parse::Yapp

于 2012-11-22T03:51:24.940 回答