php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #66664 preg_match_all + PREG_PATTERN_ORDER + PCRE_INFO_JCHANGED, output wrong result
Submitted: 2014-02-07 19:03 UTC Modified: 2016-09-10 00:25 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: coolwust at gmail dot com Assigned: cmb (profile)
Status: Closed Package: PCRE related
PHP Version: 5.5.9 OS: 3.12-1-amd64 Debian 3.12.
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: coolwust at gmail dot com
New email:
PHP Version: OS:

 

 [2014-02-07 19:03 UTC] coolwust at gmail dot com
Description:
------------
---
From manual page: http://www.php.net/function.preg-match-all
---

The code is from pcre manual, chapter 'NAMED SUBPATTERNS', line 6093:
http://www.pcre.org/pcre.txt

PREG_SET_ORDER:
Output the same result as the manual expected.

PREG_PATTERN_ORDER
Output the wrong result. Please check example for details.
Maybe the latest named capturing overwrite the previous result.

Test script:
---------------
$pattern = <<<'PATTERN'
/(?xJ)
(?<DN>Mon|Fri|Sun)(?:day)?|
(?<DN>Tue)(?:sday)?|
(?<DN>Wed)(?:nesday)?|
(?<DN>Thu)(?:rsday)?|
(?<DN>Sat)(?:urday)?
/
PATTERN;
$subject = "Monday\nThursday";
$result1 = preg_match_all($pattern, $subject, $matches1, PREG_PATTERN_ORDER);
$result2 = preg_match_all($pattern, $subject, $matches2, PREG_SET_ORDER);
echo 'subject:';
var_dump($subject);
echo 'pattern:';
var_dump($pattern);
echo 'flag PREG_PATTERN_ORDER:';
var_dump($matches1);
echo 'flag PREG_SET_ORDER:';
var_dump($matches2);


Expected result:
----------------
subject:

string 'Monday
Thursday' (length=15)

pattern:

string '/(?xJ)
(?<DN>Mon|Fri|Sun)(?:day)?|
(?<DN>Tue)(?:sday)?|
(?<DN>Wed)(?:nesday)?|
(?<DN>Thu)(?:rsday)?|
(?<DN>Sat)(?:urday)?
/' (length=123)

flag PREG_PATTERN_ORDER:

array (size=7)
  0 => 
    array (size=2)
      0 => string 'Monday' (length=6)
      1 => string 'Thursday' (length=8)
  'DN' => 
    array (size=2)
      0 => string 'Mon' (length=0)  //Expected
      1 => string 'Thu' (length=0)  //Expected
  1 => 
    array (size=2)
      0 => string 'Mon' (length=3)
      1 => string '' (length=0)
  2 => 
    array (size=2)
      0 => string '' (length=0)
      1 => string '' (length=0)
  3 => 
    array (size=2)
      0 => string '' (length=0)
      1 => string '' (length=0)
  4 => 
    array (size=2)
      0 => string '' (length=0)
      1 => string 'Thu' (length=3)
  5 => 
    array (size=2)
      0 => string '' (length=0)
      1 => string '' (length=0)

flag PREG_SET_ORDER:

array (size=2)
  0 => 
    array (size=3)
      0 => string 'Monday' (length=6)
      'DN' => string 'Mon' (length=3)
      1 => string 'Mon' (length=3)
  1 => 
    array (size=6)
      0 => string 'Thursday' (length=8)
      'DN' => string 'Thu' (length=3)
      1 => string '' (length=0)
      2 => string '' (length=0)
      3 => string '' (length=0)
      4 => string 'Thu' (length=3)

Actual result:
--------------
subject:

string 'Monday
Thursday' (length=15)

pattern:

string '/(?xJ)
(?<DN>Mon|Fri|Sun)(?:day)?|
(?<DN>Tue)(?:sday)?|
(?<DN>Wed)(?:nesday)?|
(?<DN>Thu)(?:rsday)?|
(?<DN>Sat)(?:urday)?
/' (length=123)

flag PREG_PATTERN_ORDER:

array (size=7)
  0 => 
    array (size=2)
      0 => string 'Monday' (length=6)
      1 => string 'Thursday' (length=8)
  'DN' => 
    array (size=2)
      0 => string '' (length=0)  //Wrong
      1 => string '' (length=0)  //Wrong
  1 => 
    array (size=2)
      0 => string 'Mon' (length=3)
      1 => string '' (length=0)
  2 => 
    array (size=2)
      0 => string '' (length=0)
      1 => string '' (length=0)
  3 => 
    array (size=2)
      0 => string '' (length=0)
      1 => string '' (length=0)
  4 => 
    array (size=2)
      0 => string '' (length=0)
      1 => string 'Thu' (length=3)
  5 => 
    array (size=2)
      0 => string '' (length=0)
      1 => string '' (length=0)

flag PREG_SET_ORDER:

array (size=2)
  0 => 
    array (size=3)
      0 => string 'Monday' (length=6)
      'DN' => string 'Mon' (length=3)
      1 => string 'Mon' (length=3)
  1 => 
    array (size=6)
      0 => string 'Thursday' (length=8)
      'DN' => string 'Thu' (length=3)
      1 => string '' (length=0)
      2 => string '' (length=0)
      3 => string '' (length=0)
      4 => string 'Thu' (length=3)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-04-13 14:22 UTC] cmb@php.net
-Type: Bug +Type: Documentation Problem
 [2015-04-13 14:22 UTC] cmb@php.net
> Maybe the latest named capturing overwrite the previous result.

Yes, that is exactly what's happening. Consider the following
simplified test script:

    preg_match_all(
        '/(?J)(?<match>foo)|(?<match>bar)/',
        'foo bar',
        $matches,
        PREG_PATTERN_ORDER
    );
    var_dump($matches);
    
which outputs:

    array(4) {
      [0] =>
      array(2) {
        [0] =>
        string(3) "foo"
        [1] =>
        string(3) "bar"
      }
      'match' =>
      array(2) {
        [0] =>
        string(0) ""
        [1] =>
        string(3) "bar"
      }
      [1] =>
      array(2) {
        [0] =>
        string(3) "foo"
        [1] =>
        string(0) ""
      }
      [2] =>
      array(2) {
        [0] =>
        string(0) ""
        [1] =>
        string(3) "bar"
      }
    }
    
And actually, that behavior is pretty much to be expected when
using duplicate named subpatterns in combination with
preg_match_all() and PREG_PATTERN_ORDER.

It seems to me that this is not a bug, but rather something that
should be better documented.
 [2016-07-02 14:44 UTC] cmb@php.net
-Assigned To: +Assigned To: cmb
 [2016-09-10 00:25 UTC] cmb@php.net
Automatic comment from SVN on behalf of cmb
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=340012
Log: Fix #66664: preg_match_all + PREG_PATTERN_ORDER + PCRE_INFO_JCHANGED, output wrong result
 [2016-09-10 00:25 UTC] cmb@php.net
-Status: Assigned +Status: Closed
 [2020-02-07 06:06 UTC] phpdocbot@php.net
Automatic comment on behalf of cmb
Revision: http://git.php.net/?p=doc/en.git;a=commit;h=441f9436b48956b1f17ccbf528232f28f17302c4
Log: Fix #66664: preg_match_all + PREG_PATTERN_ORDER + PCRE_INFO_JCHANGED, output wrong result
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Jul 03 08:01:34 2025 UTC