应用许多Perl正则表达式测试的最佳方法是什么?

mik*_*ers 1 regex perl

我有一个Perl模块,它将文本与数百个正则表达式的列表进行匹配; 目前我只是或者说他们:

if (
  /?:re1/ or
  ...
  /re200$/
) { return "blah"; }
Run Code Online (Sandbox Code Playgroud)

是否有更好/更快/更少资源密集的方式来做到这一点?也许存在一个有用的模块,或者我应该将它们存储在哈希等中.

the*_*Man 10

看看Regexp::Assemble.

这来自描述:

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

因此,只需要针对一个表达式测试目标字符串,而不是使用大型表达式列表进行循环.当你有几千种模式需要处理时,这很有趣.尽最大努力产生尽可能小的图案.

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

我用它做了一些项目,这真是太神奇了.


bri*_*foy 7

perlfaq6的答案我如何有效地匹配多个正则表达式?


如何有效地匹配多个正则表达式?

(由brian d foy提供)

如果你有Perl 5.10或更高版本,这几乎是微不足道的.您只需与正则表达式对象数组进行智能匹配:

my @patterns = ( qr/Fr.d/, qr/B.rn.y/, qr/W.lm./ );

if( $string ~~ @patterns ) {
    ...
    };
Run Code Online (Sandbox Code Playgroud)

智能匹配在找到匹配时停止,因此不必尝试每个表达式.

早于Perl 5.10,你有一些工作要做.您希望每次要匹配时都避免编译正则表达式.在这个例子中,perl必须为foreach循环的每次迭代重新编译正则表达式,因为它无法知道$ pattern将是什么:

my @patterns = qw( foo bar baz );

LINE: while( <DATA> ) {
    foreach $pattern ( @patterns ) {
        if( /\b$pattern\b/i ) {
            print;
            next LINE;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

qr //运算符出现在perl 5.005中.它编译正则表达式,但不应用它.当您使用正则表达式的预编译版本时,perl会减少工作量.在这个例子中,我插入了一个地图,将每个模式转换为预编译形式.脚本的其余部分是相同的,但速度更快:

my @patterns = map { qr/\b$_\b/i } qw( foo bar baz );

LINE: while( <> ) {
    foreach $pattern ( @patterns ) {
        if( /$pattern/ )
            {
            print;
            next LINE;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

在某些情况下,您可以将多个模式组合成一个正则表达式.请注意需要回溯的情况.

my $regex = join '|', qw( foo bar baz );

LINE: while( <> ) {
    print if /\b(?:$regex)\b/i;
    }
Run Code Online (Sandbox Code Playgroud)

有关正则表达式效率的更多详细信息,请参阅Jeffrey Freidl掌握正则表达式.他解释了正则表达式引擎如何工作以及为什么某些模式效率低得惊人.一旦了解了perl如何应用正则表达式,您就可以针对各种情况调整它们.