|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2017-09-11 06:28 UTC] spam2 at rhsoft dot net
[2017-09-11 06:56 UTC] kelunik@php.net
-Status: Open
+Status: Not a bug
[2017-09-11 06:56 UTC] kelunik@php.net
[2017-09-11 09:10 UTC] jocrutrisi at ibsats dot com
[2017-09-12 12:51 UTC] kelunik@php.net
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Oct 27 10:00:01 2025 UTC |
Description: ------------ PCRE differentiates "a sub-pattern that matched and is empty" from "a sub-pattern that didn't match". But in PHP's exposed APIs both of these cases produce a sub-pattern key with an empty match. Probably this can be a flag, for unfortunate B.C. reasons, but the current behavior is certainly not correct. Test script: --------------- $re = '%^ ((?=x))? ((?=y))? (\w) $%mx'; $str = 'x y z'; preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0); // Print the entire match result var_dump($matches); Expected result: ---------------- Observe the identical PCRE regex and input on Regex101, notice the flag "isParticipating" clearly points out which pattern matched (even if empty) or didn't match: [ [ { "content": "x", "isParticipating": true, "groupNum": 0, }, { "content": "", "isParticipating": true, "groupNum": 1, }, { "content": "", "isParticipating": false, "groupNum": 2, }, { "content": "x", "isParticipating": true, "groupNum": 3, } ], [ { "content": "y", "isParticipating": true, "groupNum": 0, }, { "content": "", "isParticipating": false, "groupNum": 1, }, { "content": "", "isParticipating": true, "groupNum": 2, }, { "content": "y", "isParticipating": true, "groupNum": 3, } ], [ { "content": "z", "isParticipating": true, "groupNum": 0, }, { "content": "", "isParticipating": false, "groupNum": 1, }, { "content": "", "isParticipating": false, "groupNum": 2, }, { "content": "z", "isParticipating": true, "groupNum": 3, } ] ] Source: https://regex101.com/r/N90TJE/1 Actual result: -------------- Both matching-and-empty and non-matching are just empty strings, we can't tell them apart: array(3) { [0]=> array(4) { [0]=> string(1) "x" [1]=> string(0) "" [2]=> string(0) "" [3]=> string(1) "x" } [1]=> array(4) { [0]=> string(1) "y" [1]=> string(0) "" [2]=> string(0) "" [3]=> string(1) "y" } [2]=> array(4) { [0]=> string(1) "z" [1]=> string(0) "" [2]=> string(0) "" [3]=> string(1) "z" } }