7

这个:

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

给了我这个:

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

我对此有点困惑。我知道第 1 组给了我一个空字符串,因为这是一个惰性匹配。但不(bar)?应该贪婪,从而给我捕获第 2 组吗?

在我看来,我应该得到的是合理的

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

空间在哪里[1]。然而..这并没有发生。为什么?

4

3 回答 3

5

这里的答案非常简单。第一组不匹配(第一次通过),甚至不匹配空格。第二组尝试将空格与“bar”匹配,这当然失败了。如果后面有任何东西要匹配,引擎现在将回溯并扩展第一个捕获组以匹配空间。但它现在的方式非常好(第二组实际上可以是空的),所以它就保持这种状态。

要产生您期望的结果,请尝试以下操作:

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


在您的编辑中,您添加了另一个捕获组。(.*) 现在是 2。它匹配到字符串的末尾,就像你想象的那样。所以你是对的,你只是改变了例子^^

于 2013-11-03T21:30:43.280 回答
3

不,这种行为是正确的。从关于惰性匹配的文档中

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

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

于 2013-11-03T21:30:56.657 回答
2

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

于 2013-11-03T21:31:50.990 回答