I'm confused by a difference I found between the way JavaScript and PHP handle the following regex.
In JavaScript,
'foobar'.replace(/(?=(bar))/ , '$1');
'foobar'.replace(/(?=(bar))?/ , '$1');
'foobar'.replace(/(?:(?=(bar)))?/, '$1');
results in, respectively,
foobarbar
foobar
foobar
as shown in this jsFiddle .
However, in PHP,
echo preg_replace('/(?=(bar))/', '$1', "foobar<br/>");
echo preg_replace('/(?=(bar))?/', '$1', "foobar<br/>");
echo preg_replace('/(?:(?=(bar)))?/', '$1', "foobar<br/>");
results in,
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
I'm not so much worried about the warning. But it appears that in JavaScript, lookahead assertions are somehow "lazier" than in PHP. Why the difference? Is this a bug in one of the engines? Which is theoretically more "correct"?
The real difference is actually very simple:
In JavaScript, replace
will only replace the first match , unless using the /g
flag (global).
In PHP, preg_replace
replaces all matches.
The third pattern, (?:(?=(bar)))?
, can match the empty string in every position, and captures "bar"
in some positions. Without the /g
flag, it only matches once, at the beginning of the string.
You would have easily seen the difference had you used a more visible replacement string, like [$1]
.
PHP Example: http://ideone.com/8Mjg6
JavaScript Example, no /g
: http://jsfiddle.net/qKb4b/3/
JavaScript Example, with /g
: http://jsfiddle.net/qKb4b/2/
I would also note that "laziness" is a different concept in regular expressions, not related to this question.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.