Bug #80645 [Opn]: PHPs behavior of empty string matching is incorrect
| From: | cmb@php.net | Date: | Tue, 19 Jan 2021 13:27:41 +0000 |
| Subject: | Bug #80645 [Opn]: PHPs behavior of empty string matching is incorrect | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-231637@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=80645&edit=1
ID: 80645
Updated by: cmb@php.net
Reported by: firas dot dib at gmail dot com
Summary: PHPs behavior of empty string matching is incorrect
Status: Open
Type: Bug
Package: PCRE related
Operating System: n/a
PHP Version: 8.0.1
Block user comment: N
Private report: N
New Comment:
Respective commit of PCRE2:
<https://vcs.pcre.org/pcre2?view=revision&revision=955>.
Previous Comments:
------------------------------------------------------------------------
[2021-01-19 13:03:55] firas dot dib at gmail dot com
Description:
------------
PHP is currently not matching empty strings in a perl compatible way.
If we use the following regex: /(?<=(\G.{2}))(?!$)/g
and the following string: 123456789
We would get the following results in PCRE1 and PHP (both PHP <7.3 and >=7.3): "12",
"45", "78"
However, in PCRE2 (and Perl), we would get: "12", "34", "56",
"78"
This can be verified by using pcre2test and perltest that is bundled with PCRE2.
The changelog for PCRE2 10.32 states the following:
21. In both pcre2test and pcre2_substitute(), with global matching, a pattern
that matched an empty string, but never at the starting match offset, was not
handled in a Perl-compatible way. The pattern /(<?=\G.)/ is an example of such
a pattern. Because \G is in a lookbehind assertion, there has to be a
"bumpalong" before there can be a match. The automatic "advance by one
character after an empty string match" rule is therefore inappropriate. A more
complicated algorithm has now been implemented.
I am not sure if this behavior is intentional or not, but figured I'd highlight it to you.
Best,
Firas
Test script:
---------------
<?php
preg_match_all("/(?<=(\G.{2}))(?!$)/", "123456789", $matches);
var_dump($matches);
?>
Expected result:
----------------
"12", "34", "56", "78"
Actual result:
--------------
"12", "45", "78"
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=80645&edit=1