在多个文本上搜索相同正则表达式的有效方法

时间:2011-12-03 14:15:18

标签: regex perl

我有多个文本字段,每个字段都是文本段落,我想使用正则表达式在这些字段上搜索特定模式,例如:

my $text1 =~/(my pattern)/ig;
my $text2 =~/(my pattern)/ig;
...
my $textn=~/(my pattern)/ig;

我想知道在perl上使用相同的正则表达式搜索多个文本是否有效,或者我应该使用上述格式?

3 个答案:

答案 0 :(得分:13)

使用topicaliser。

for ($text1, $text2, $textn) {
    /(my pattern)/ig && do { ... };
}

当您有编号变量时,它是一个红色标记,您应该考虑使用复合数据结构。使用简单的数组看起来几乎相同:

for (@texts) {

答案 1 :(得分:2)

my $pattern = qr/((?:i)my pattern)/;
my @matches;
push @matches, $text1 =~ /$pattern/g;
push @matches, $text2 =~ /$pattern/g;
push @matches, $textn =~ /$pattern/g;

这就像我能想到的那样高效 - 理论上预编译一次正则表达式,虽然我不确定是否将它插回到//以获得'g'修饰符撤消任何编译。当然,我也不得不怀疑这是否真的是一个瓶颈,如果你只是在看一些过早的优化。

答案 2 :(得分:0)

这个问题的答案取决于你的模式是否包含任何变量。如果没有,perl已经足够聪明,只能构建一次RE,只要它在任何地方都是相同的。

现在,如果你确实使用变量,那么@ Tanktalus的回答很接近,但通过再次编译RE会增加不必要的复杂性。

使用此:

my @matches;
push @matches, $text1 =~ /((?:i)my pattern with a $variable)/o;
push @matches, $text2 =~ /((?:i)my pattern with a $variable)/o;
push @matches, $textn =~ /((?:i)my pattern with a $variable)/o;

为什么?

通过在RE模式中使用变量,perl被强制为每个实例重新编译,即使该变量是@ Tanktalus的答案中的预编译RE。 /o确保它只在第一次遇到时编译一次,但是对于代码中的每个出现,它仍然必须编译一次。这是因为Perl无法知道$ pattern是否在不同用途之间发生了变化。

其他考虑因素

在实践中,正如@Tanktalus所说,我怀疑这是一个过早优化的大肥。 /o /只在你的模式包含变量时才重要(否则perl非常聪明,只能编译一次!)

使用@Tanktalus建议的预编译RE的更有用的原因是提高代码可读性。如果你有一个大毛茸茸的RE,那么在任何地方使用$ pattern都会大大提高可读性,并且性能成本很低(你不会注意到的)。

结论

如果你的RE包含变量,只需使用/o(除非你真的需要变量在每次运行时更改RE),否则不要担心它。