为什么看起来Perl正则表达式中的*不是贪婪的?

时间:2009-07-12 21:21:03

标签: regex perl

我希望这会打印"[b]",但会打印"[]"

$x = "abc";
$x =~ /(b*)/;
print "[$1]";

如果用加号代替星号,它就像我期望的那样。是不是加号和明星都应该贪婪?

ADDED:感谢大家指出(在几秒钟内,似乎!)“b *”匹配空字符串,第一次出现在字符串开始之前。所以贪婪根本不是问题。它甚至在到达第一个'b'之前匹配空字符串。

6 个答案:

答案 0 :(得分:10)

模式将匹配并在第一次b*为真时返回,即它将在a执行零宽度匹配。为了更清楚地说明发生了什么,请执行以下操作:

$x = "zabc";
$x =~ /(.b*)/;
print "[$1]";

答案 1 :(得分:10)

贪婪,但b*将匹配空字符串。 任何 *将始终匹配空字符串,

  "abc"
  /\
     --- matches the empty string here.

如果你打印$',你会看到它是abc,这是匹配后字符串的其余部分。贪婪只是意味着在“bbb”的情况下,你得到“bbb”,而不是“b”或“bb”。

答案 2 :(得分:3)

正则表达式将匹配a(backtrack)(自正则表达式回溯后为空值)并结束。使用+量词时,它与ac不匹配,因此$1的值变为b

答案 3 :(得分:3)

正则表达式匹配字符串中最早的点。在'abc'=〜/(b *)/的情况下,该点位于字符串的开头,它可以匹配零b。如果您曾尝试匹配'bbc',那么您将打印出来:

[BB]

答案 4 :(得分:1)

尽可能早地匹配比匹配的长度具有更高的优先级(AFAIR这是Perl的正则表达式匹配引擎的情况,这是NFA)。因此,字符串开头的零长度匹配比字符串后面的较长匹配更合适。

有关详细信息,请在此article中搜索有关正则表达式匹配引擎的“DFA与NFA”。

答案 5 :(得分:0)

模式结尾的A *几乎总是不是你想要的。我们甚至将此作为 Learning Perl 中的一个技巧问题来说明这个问题。