Bug #76221 [Opn]: last optional capturing group is not included
Edit report at https://bugs.php.net/bug.php?id=76221&edit=1
ID: 76221
Updated by: requinix@php.net
Reported by: wes dot nospam at nospam dot example dot org
-Summary: last optional capturing group is not included when
using PREG_UNMATCHED_AS_NULL
+Summary: last optional capturing group is not included
Status: Open
Type: Bug
Package: PCRE related
PHP Version: 7.2.4
Block user comment: N
Private report: N
New Comment:
PCRE2 returns to PHP the highest number of the successful capturing groups. In this pattern, while
there are 2 groups the highest to capture was #1. PHP then only fills in the data for the array up
to that group and doesn't continue filling in the rest after it. This happens with or without
PREG_UNMATCHED_AS_NULL enabled.
https://www.pcre.org/current/doc/html/pcre2api.html#SEC29
> Offset values that correspond to unused subpatterns at the end of the expression are also set
> to PCRE2_UNSET. For
> example, if the string "abc" is matched against the pattern (abc)(x(yz)?)?
> subpatterns 2 and 3 are not matched. The
> return from the function is 2, because the highest used capturing subpattern number is 1.
You can see that the option itself works correctly by having a later capturing group match, such as
with /^(aaa)(?:(x)?)(y)/. Then [1] and [3] will be set while [2] will be null/an empty string.
The most obvious solution is for PHP to determine the number of capturing groups with
pcre2_pattern_info() and the PCRE2_INFO_CAPTURECOUNT option instead of using the return value from
pcre2_match/pcre2_jit_match.
https://www.pcre.org/current/doc/html/pcre2api.html#TOC1
Previous Comments:
------------------------------------------------------------------------
[2018-04-14 11:59:39] wes dot nospam at nospam dot example dot org
Description:
------------
Not sure this is a bug, adding in case it is.
There are two capturing groups in the regexp,
so I expect $matches to be of length 3.
https://3v4l.org/1ulVZ
hope this helps...
Test script:
---------------
preg_match("/^(aaa)(?:(x)?)/", "aaay", $matches, PREG_UNMATCHED_AS_NULL);
var_dump($matches);
Expected result:
----------------
array(2) {
[0]=>
string(3) "aaa"
[1]=>
string(3) "aaa"
[2]=>
NULL
}
Actual result:
--------------
array(2) {
[0]=>
string(3) "aaa"
[1]=>
string(3) "aaa"
}
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=76221&edit=1
Thread (4 messages)