php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80569 preg_match no empty (null or "") values in matches
Submitted: 2020-12-31 17:08 UTC Modified: 2021-01-01 14:29 UTC
From: shardlow dot a at gmail dot com Assigned:
Status: Open Package: PCRE related
PHP Version: 7.4.13 OS: OSX Catalina
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2020-12-31 17:08 UTC] shardlow dot a at gmail dot com
Description:
------------
---
From manual page: https://php.net/function.preg-match
---



Test script:
---------------
       //print_r($_GET);
        //$value = '1:2.3';
        //$value = '1:2';
        $value = '2';
        $matches = '';
        preg_match('/^(\d{1,2}:)?(\d{1,2})(\.\d{1,2})?$/', $value, $matches);
        echo '<br>';
        echo '<br>';
        print_r($matches);
        echo '<br>';
        echo phpversion();

Expected result:
----------------
Array ( [0] => 2 [1] => [2] => 2 [3]=>)
7.3.11

Actual result:
--------------
Array ( [0] => 2 [1] => [2] => 2 )
7.3.11

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-12-31 20:18 UTC] requinix@php.net
-Status: Open +Status: Not a bug -Package: *Regular Expressions +Package: PCRE related
 [2020-12-31 20:18 UTC] requinix@php.net
Use PREG_UNMATCHED_AS_NULL.
 [2021-01-01 12:17 UTC] shardlow dot a at gmail dot com
You have misunderstood the problem and so your solution does not work. The suggestion of using PREG_UNMATCHED_AS_NULL only changes "" to null in the matches array. The problem remains that an unmatched optional group is not guaranteed to produce a value in the matches array.  I can test for this using isset but this is inelegant and of greater concern is that I am uncertain as to whether there remains a consistent clear mapping between the group order in the pattern and the indices of the matches where present.  With the pattern containing three groups in my example and a value of '1' (which is valid representing just one minute) the match array contains just 3 entries but should contain 4 (the zeroth entry is always the total match).  The first group is optional but IS graced with a null entry.  The last group is optional and IS NOT. If the first group did not produce a null entry the mapping from group order to index would be broken. Hopefully this does not happen. I suspect trailing optional groups fail to generate entries in the matches array.  If the latter the thing is workable (if inelegant) but this should be clearly documented.
 [2021-01-01 14:29 UTC] cmb@php.net
-Status: Not a bug +Status: Open
 [2021-01-01 14:29 UTC] cmb@php.net
Interestingly, basically the same issue had been reported for
preg_match_all() as bug #13635, and has been fixed[1] back then.
I wonder whether the behavioral difference of preg_match() is
intended, or whether that was just overlooked.

At least we need to document that unmatched *trailing*
subpatterns are omitted from the $matches.

[1] <https://github.com/php/php-src/commit/3942e2a8bdf87a40949788df6e2a92ba40acf2ab>
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Thu Mar 04 07:01:26 2021 UTC