php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81486 named capture group key missing if not found if not using PREG_UNMATCHED_AS_NULL
Submitted: 2021-09-29 06:50 UTC Modified: 2021-09-29 09:05 UTC
From: hkirsman at gmail dot com Assigned:
Status: Not a bug Package: PCRE related
PHP Version: 7.4.24 OS: Linux (Docker container)
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 this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: hkirsman at gmail dot com
New email:
PHP Version: OS:

 

 [2021-09-29 06:50 UTC] hkirsman at gmail dot com
Description:
------------
My PHP version is actually 7.4.23.

My issue is that I have regex named capture group (to catch language from URL)    and sometimes the key is not there if nothing is found. It was working fine at some point as it was returning keys with empty strings. At some point keys were not there anymore. All I could think of is that I had made small changes to my regex.

Is this a bug or working ok? I've added more comments in the script.

Test script:
---------------
<?php

$path = '/elearning';
# Does not add empty lang to $matches.
$regex_path_lang_match_not_found = '#/(?P<lang>[^/]+/)?elearning#';
# Adds empty lang to $matches.
$regex_path_empty_lang_match_found = '#(?P<lang>)/elearning$#';

$regex_match = preg_match($regex_path_lang_match_not_found . 'u', $path, $matches);
// Doc says If PREG_UNMATCHED_AS_NULL flag is passed, unmatched subpatterns are
// reported as null; otherwise they are reported as an empty string.
echo 'lang key is gone but should it?';
print_r($matches);

$regex_match = preg_match($regex_path_lang_match_not_found . 'u', $path, $matches, PREG_UNMATCHED_AS_NULL);
echo 'PREG_UNMATCHED_AS_NULL adds it back';
print_r($matches);

$regex_match = preg_match($regex_path_empty_lang_match_found . 'u', $path, $matches);
echo 'Similar regex, lang is not matched, but key exists';
print_r($matches);


Expected result:
----------------
lang key is gone but should it?Array
(
    [0] => /elearning
    [lang] => 
    [1] => 
)
PREG_UNMATCHED_AS_NULL adds it backArray
(
    [0] => /elearning
    [lang] => 
    [1] => 
)
Similar regex, lang is not matched, but key existsArray
(
    [0] => /elearning
    [lang] => 
    [1] => 
)


Actual result:
--------------
lang key is gone but should it?Array
(
    [0] => /elearning
)
PREG_UNMATCHED_AS_NULL adds it backArray
(
    [0] => /elearning
    [lang] => 
    [1] => 
)
Similar regex, lang is not matched, but key existsArray
(
    [0] => /elearning
    [lang] => 
    [1] => 
)


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-09-29 07:22 UTC] requinix@php.net
-Summary: named capture group key missing if not found +Summary: named capture group key missing if not found if not using PREG_UNMATCHED_AS_NULL -Status: Open +Status: Not a bug -Package: *General Issues +Package: PCRE related
 [2021-09-29 07:22 UTC] requinix@php.net
Without using PREG_UNMATCHED_AS_NULL, an unmatched group may or may not report as an empty string depending on circumstances that aren't entirely obvious.
https://3v4l.org/MjB11

PREG_UNMATCHED_AS_NULL was added to PHP specifically to normalize this behavior and ensure that an unmatched group is always added to the match array, and with a null value to distinguish it from a match of a zero-length string.
https://3v4l.org/4H7GJ

The answer to your problem is probably either PREG_UNMATCHED_AS_NULL or simply ??
 [2021-09-29 09:05 UTC] hkirsman at gmail dot com
I've currently solved it with PREG_UNMATCHED_AS_NULL and seems to work fine.
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Tue May 17 05:05:45 2022 UTC