当正则表达式与*对照组时,为什么Perl会变懒?

时间:2013-07-09 00:06:03

标签: regex perl

在perl中,*通常是贪婪的,除非你在它之后添加?。但是,当*用于某个群组时,情况似乎有所不同。我的问题是“为什么”。考虑这个例子:

my $text = 'f fjfj ff';
my (@matches) = $text =~ m/((?:fj)*)/;
print "@matches\n";
# --> ""
@matches = $text =~ m/((?:fj)+)/;
print "@matches\n";
# --> "fjfj"

在第一场比赛中,perl懒洋洋地打印出任何东西,虽然它可以匹配某些东西,如第二场比赛所示。奇怪的是,当组的内容只是*而不是实际字符时,.的行为会如预期般贪婪:

@matches = $text =~ m/((?:..)*)/;
print "@matches\n";
# --> 'f fjfj f'
  1. 注意:以上是在perl 5.12上测试的。
  2. 注意:我是否对内部组使用捕获或非捕获括号无关紧要。

2 个答案:

答案 0 :(得分:15)

这不是贪婪或懒惰的重复问题。 (?:fj)* 贪婪匹配尽可能多的“fj”重复,但成功匹配零重复。当您尝试将其与字符串"f fjfj ff"匹配时,它将首先尝试匹配位置零(在第一个“f”之前)。在零位置成功匹配“fj”的最大次数为零,因此模式成功匹配空字符串。由于模式在零位置成功匹配,我们已经完成,并且引擎没有理由在稍后的位置尝试匹配。

故事的寓意是:不要写出任何可以匹配的模式,除非你想要它什么都不匹配。

答案 1 :(得分:7)

Perl将尽可能早地匹配字符串(最左侧)。它可以通过匹配字符串开头的fj的零次出现来完成第一次匹配。