php / php/php-src

preg_match is inconsistent in how it handles unmatched capturing groups

Offen
#17,934 8 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bug Extension: pcre Status: Needs Triage
Vorherrschende Sprache
C
Sterne
40.4k
Forks
8.2k
Ø Merge
2 T. 13 Std.
Gemergte PRs (30 T.)
96

Beschreibung

Description

The following code:

<?php
$pattern = '/A(?<a>a)|B(?<b>b)/';
preg_match($pattern, 'Aa', $matches);
echo json_encode($matches)."\n";
preg_match($pattern, 'Bb', $matches);
echo json_encode($matches)."\n";

Resulted in this output:

{"0":"Aa","a":"a","1":"a"}
{"0":"Bb","a":"","1":"","b":"b","2":"b"}

But I expected this output instead:

{"0":"Aa","a":"a","1":"a"}
{"0":"Bb","b":"b","2":"b"}

I would expect that a capturing group only appears in the match if the pattern captured that group. However, it seems like in some cases groups on the left side of an alternation will appear with an empty string as the value while groups on the right side are omitted when they aren't captured.

This makes it difficult to easily ask "Did group N get captured?" because, depending on the structure of the regex, sometimes "not captured" will report as empty string and sometimes it will report as an omitted key. The problem is even more confusing if empty string was a possible capture for the group; in that case there's no way to tell what happened without using PREG_OFFSET_CAPTURE which gives -1 for the extraneous matches.

PHP Version

PHP 8.2.12

Operating System

Windows 11

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne damit, das preg_match-Beispiel unter PHP 8.2.12 zu reproduzieren, und vergleiche die Matches-Arrays für beide Alternativen. Verfolge die Behandlung nicht übereinstimmender Capturing-Gruppen in der Implementierung von preg_match und füge anschließend einen Regressionstest hinzu oder aktualisiere einen, sodass nicht übereinstimmende Gruppen eine konsistente Ausgabe haben und das gezeigte erwartete Ergebnis erzeugt wird.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
php
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.