php理解贪婪与非贪婪的匹配

时间:2013-11-03 21:22:43

标签: php regex

此:

preg_match('~foo(.*?)(bar)?~','foo bar',$m);

给了我这个:

Array
(
    [0] => foo
    [1] => 
)

我对此感到困惑。我得到那个组1给我一个空字符串,因为它是一个懒惰的匹配。但不应该(bar)?贪婪,从而给我捕获组2?

对我而言,我应该得到的是

Array
(
    [0] => foo
    [1] => 
    [2] => bar
)

其中[1]是一个空格。然而......这不会发生。为什么?

3 个答案:

答案 0 :(得分:5)

这里的答案非常简单。第一组没有任何东西(第一次传球),甚至没有空间。第二组尝试将空格与“bar”匹配,当然,这会失败。如果有什么背后的东西要匹配,引擎现在会回溯并扩展第一个捕获组以匹配空间。但它现在的状态非常好(第二组实际上可以是emtpy),所以它就是这样。

为了产生你的期望,试试这个:

preg_replace('~foo(.*?)(bar)?_~', 'foo bar_', $m);

<小时/> 在编辑中,您添加了另一个捕获组。 (。*)现在是2.它匹配到字符串的结尾,正如你所想的那样。所以你就是那个,你刚刚改变了例子^^

答案 1 :(得分:3)

不,这种行为是正确的。来自documentation on lazy matching

  

如果量词后跟一个问号,那么它会变得懒惰,而是匹配可能的最小次数

由于(bar)?是可选的,(.*?)不需要匹配任何内容以使正则表达式成功。由于未捕获 foo bar 之间的空格,因此表达式无法继续并匹配 bar

答案 2 :(得分:2)

条目'0'始终是完全匹配的模式,在这种情况下是 foo 。 然而,第一个匹配组不匹配任何*使用。第二组是可选的。