11

在 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. 注意:无论我对内部组使用捕获括号还是非捕获括号都没有关系。
4

2 回答 2

15

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

这个故事的寓意是:不要写一个什么都不匹配的模式,除非你想让它什么都不匹配。

于 2013-07-09T00:10:31.430 回答
7

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

于 2013-07-09T00:11:05.027 回答