3

我发现 JavaScript 和 PHP 处理以下正则表达式的方式之间存在差异,我感到很困惑。

在 JavaScript 中,

'foobar'.replace(/(?=(bar))/     , '$1');
'foobar'.replace(/(?=(bar))?/    , '$1');
'foobar'.replace(/(?:(?=(bar)))?/, '$1');

结果分别为

foobarbar
foobar
foobar

如这个jsFiddle所示。

然而,在 PHP 中,

echo preg_replace('/(?=(bar))/', '$1', "foobar<br/>");
echo preg_replace('/(?=(bar))?/', '$1', "foobar<br/>");
echo preg_replace('/(?:(?=(bar)))?/', '$1', "foobar<br/>");

结果是,

foobarbar

Warning: preg_replace() [function.preg-replace]: Compilation failed: nothing to repeat at offset 9 in /homepages/26/d94605010/htdocs/lz/writecodeonline.com/php/index.php(201) : eval()'d code on line 2
foobarbar

我不太担心这个警告。但似乎在 JavaScript 中,前瞻断言在某种程度上比在 PHP 中“更懒惰”。为什么有区别?这是其中一个引擎中的错误吗?理论上哪个更“正确”?

4

1 回答 1

2

真正的区别其实很简单:

在 JavaScript 中,replace 只会替换第一个匹配项,除非使用/g标志(全局)。
在 PHP 中,preg_replace替换所有匹配项。

第三种模式,(?:(?=(bar)))?,可以匹配每个位置的空字符串,并"bar"某些位置捕获。没有/g标志,它只匹配一次,在字符串的开头。

如果您使用更明显的替换字符串(例如[$1].

PHP 示例: http: //ideone.com/8Mjg6
JavaScript 示例,无/g:http: //jsfiddle.net/qKb4b/3/
JavaScript 示例,带有:http /g: //jsfiddle.net/qKb4b/2/

我还要注意,“懒惰”是正则表达式中的一个不同概念,与这个问题无关。

于 2012-09-15T17:10:34.920 回答