Skip to content

Commit

Permalink
Fix preg_match named capturing groups
Browse files Browse the repository at this point in the history
Co-Authored-By: Michael Voříšek <[email protected]>
  • Loading branch information
2 people authored and ondrejmirtes committed Jul 12, 2024
1 parent 2505e94 commit 892eb2e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 10 deletions.
21 changes: 16 additions & 5 deletions patches/Grammar.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
--- Grammar.pp 2024-05-18 12:15:53
+++ Grammar.pp.fix 2024-05-18 12:15:05
diff --git a/Grammar.pp b/Grammar.pp
index 5157084..8384417 100644
--- a/Grammar.pp
+++ b/Grammar.pp
@@ -73,7 +73,7 @@
%token co:comment .*?(?=(?<!\\)\))

// Capturing group.
-%token named_capturing_ \(\?< -> nc
+%token named_capturing_ \(\?P?< -> nc
%token nc:_named_capturing > -> default
%token nc:capturing_name .+?(?=(?<!\\)>)
%token non_capturing_ \(\?:
@@ -109,7 +109,7 @@
// Please, see PCRESYNTAX(3), General Category properties, PCRE special category
// properties and script names for \p{} and \P{}.
Expand All @@ -9,7 +20,7 @@
%token match_point_reset \\K
%token literal \\.|.

@@ -168,7 +168,7 @@
@@ -168,7 +168,7 @@ quantifier:
::negative_class_:: #negativeclass
| ::class_::
)
Expand All @@ -18,7 +29,7 @@
::_class::

#range:
@@ -178,7 +178,7 @@
@@ -178,7 +178,7 @@ simple:
capturing()
| literal()

Expand All @@ -27,7 +38,7 @@
::comment_:: <comment>? ::_comment:: #comment
| (
::named_capturing_:: <capturing_name> ::_named_capturing:: #namedcapturing
@@ -191,6 +191,7 @@
@@ -191,6 +191,7 @@ capturing:

literal:
<character>
Expand Down
25 changes: 22 additions & 3 deletions tests/PHPStan/Analyser/nsrt/preg_match_shapes.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,9 @@ function doNonCapturingGroup(string $s): void {

function doNamedSubpattern(string $s): void {
if (preg_match('/\w-(?P<num>\d+)-(\w)/', $s, $matches)) {
// could be assertType('array{0: string, num: string, 1: string, 2: string, 3: string}', $matches);
assertType('array<string>', $matches);
assertType('array{0: string, num: string, 1: string, 2: string}', $matches);
}
assertType('array<string>', $matches);
assertType('array{}|array{0: string, num: string, 1: string, 2: string}', $matches);

if (preg_match('/^(?<name>\S+::\S+)/', $s, $matches)) {
assertType('array{0: string, name: string, 1: string}', $matches);
Expand Down Expand Up @@ -364,3 +363,23 @@ function bug11291(string $s): void {
}
assertType('array{}|array{0: string, 1: string, 2?: string, 3?: string}', $matches);
}

function bug11323a(string $s): void
{
if (preg_match('/Price: (?P<currency>£|€)\d+/', $s, $matches)) {
assertType('array{0: string, currency: string, 1: string}', $matches);
} else {
assertType('array{}', $matches);
}
assertType('array{}|array{0: string, currency: string, 1: string}', $matches);
}

function bug11323b(string $s): void
{
if (preg_match('/Price: (?<currency>£|€)\d+/', $s, $matches)) {
assertType('array{0: string, currency: string, 1: string}', $matches);
} else {
assertType('array{}', $matches);
}
assertType('array{}|array{0: string, currency: string, 1: string}', $matches);
}
4 changes: 2 additions & 2 deletions tests/PHPStan/Analyser/nsrt/preg_match_shapes_php82.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function doNonAutoCapturingFlag(string $s): void {
assertType('array{}|array{string, string}', $matches);

if (preg_match('/(\d+)(?P<num>\d+)/n', $s, $matches)) {
assertType('array<string>', $matches); // could be 'array{0: string, num: string, 1: string}'
assertType('array{0: string, 1: string, num: string, 2: string}', $matches);
}
assertType('array<string>', $matches);
assertType('array{}|array{0: string, 1: string, num: string, 2: string}', $matches);
}

0 comments on commit 892eb2e

Please sign in to comment.