Skip to content

Commit 892eb2e

Browse files
staabmmvorisek
authored andcommitted
Fix preg_match named capturing groups
Co-Authored-By: Michael Voříšek <[email protected]>
1 parent 2505e94 commit 892eb2e

File tree

3 files changed

+40
-10
lines changed

3 files changed

+40
-10
lines changed

patches/Grammar.patch

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
1-
--- Grammar.pp 2024-05-18 12:15:53
2-
+++ Grammar.pp.fix 2024-05-18 12:15:05
1+
diff --git a/Grammar.pp b/Grammar.pp
2+
index 5157084..8384417 100644
3+
--- a/Grammar.pp
4+
+++ b/Grammar.pp
5+
@@ -73,7 +73,7 @@
6+
%token co:comment .*?(?=(?<!\\)\))
7+
8+
// Capturing group.
9+
-%token named_capturing_ \(\?< -> nc
10+
+%token named_capturing_ \(\?P?< -> nc
11+
%token nc:_named_capturing > -> default
12+
%token nc:capturing_name .+?(?=(?<!\\)>)
13+
%token non_capturing_ \(\?:
314
@@ -109,7 +109,7 @@
415
// Please, see PCRESYNTAX(3), General Category properties, PCRE special category
516
// properties and script names for \p{} and \P{}.
@@ -9,7 +20,7 @@
920
%token match_point_reset \\K
1021
%token literal \\.|.
1122

12-
@@ -168,7 +168,7 @@
23+
@@ -168,7 +168,7 @@ quantifier:
1324
::negative_class_:: #negativeclass
1425
| ::class_::
1526
)
@@ -18,7 +29,7 @@
1829
::_class::
1930

2031
#range:
21-
@@ -178,7 +178,7 @@
32+
@@ -178,7 +178,7 @@ simple:
2233
capturing()
2334
| literal()
2435

@@ -27,7 +38,7 @@
2738
::comment_:: <comment>? ::_comment:: #comment
2839
| (
2940
::named_capturing_:: <capturing_name> ::_named_capturing:: #namedcapturing
30-
@@ -191,6 +191,7 @@
41+
@@ -191,6 +191,7 @@ capturing:
3142

3243
literal:
3344
<character>

tests/PHPStan/Analyser/nsrt/preg_match_shapes.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,9 @@ function doNonCapturingGroup(string $s): void {
9393

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

101100
if (preg_match('/^(?<name>\S+::\S+)/', $s, $matches)) {
102101
assertType('array{0: string, name: string, 1: string}', $matches);
@@ -364,3 +363,23 @@ function bug11291(string $s): void {
364363
}
365364
assertType('array{}|array{0: string, 1: string, 2?: string, 3?: string}', $matches);
366365
}
366+
367+
function bug11323a(string $s): void
368+
{
369+
if (preg_match('/Price: (?P<currency>£|€)\d+/', $s, $matches)) {
370+
assertType('array{0: string, currency: string, 1: string}', $matches);
371+
} else {
372+
assertType('array{}', $matches);
373+
}
374+
assertType('array{}|array{0: string, currency: string, 1: string}', $matches);
375+
}
376+
377+
function bug11323b(string $s): void
378+
{
379+
if (preg_match('/Price: (?<currency>£|€)\d+/', $s, $matches)) {
380+
assertType('array{0: string, currency: string, 1: string}', $matches);
381+
} else {
382+
assertType('array{}', $matches);
383+
}
384+
assertType('array{}|array{0: string, currency: string, 1: string}', $matches);
385+
}

tests/PHPStan/Analyser/nsrt/preg_match_shapes_php82.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function doNonAutoCapturingFlag(string $s): void {
1313
assertType('array{}|array{string, string}', $matches);
1414

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

0 commit comments

Comments
 (0)