Skip to content

Commit 29fd8f3

Browse files
committed
Support # comments in regex
1 parent 2d64686 commit 29fd8f3

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

src/Type/Regex/RegexGroupParser.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use function count;
2424
use function in_array;
2525
use function is_int;
26+
use function preg_replace;
2627
use function rtrim;
2728
use function sscanf;
2829
use function str_contains;
@@ -64,20 +65,28 @@ public function parseGroups(string $regex): ?array
6465
return null;
6566
}
6667

67-
$rawRegex = $this->regexExpressionHelper->removeDelimitersAndModifiers($regex);
68-
try {
69-
$ast = self::$parser->parse($rawRegex);
70-
} catch (Exception) {
71-
return null;
72-
}
73-
7468
$modifiers = $this->regexExpressionHelper->getPatternModifiers($regex) ?? '';
7569
foreach (self::NOT_SUPPORTED_MODIFIERS as $notSupportedModifier) {
7670
if (str_contains($modifiers, $notSupportedModifier)) {
7771
return null;
7872
}
7973
}
8074

75+
// The regex engine ignores everything after the (?# until the first closing parenthesis
76+
$regex = preg_replace('/\(\?#[^)]*\)/', '', $regex) ?? '';
77+
78+
if (str_contains($modifiers, 'x')) {
79+
// in freespacing mode the # character starts a comment and runs until the end of the line
80+
$regex = preg_replace('/#.*/', '', $regex) ?? '';
81+
}
82+
83+
$rawRegex = $this->regexExpressionHelper->removeDelimitersAndModifiers($regex);
84+
try {
85+
$ast = self::$parser->parse($rawRegex);
86+
} catch (Exception) {
87+
return null;
88+
}
89+
8190
$captureOnlyNamed = false;
8291
if ($this->phpVersion->supportsPregCaptureOnlyNamedGroups()) {
8392
$captureOnlyNamed = str_contains($modifiers, 'n');
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php // lint >= 7.4
2+
3+
namespace Bug12242;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
function foo(string $str): void
8+
{
9+
$regexp = '/
10+
# (
11+
([\d,]*)
12+
# )
13+
/x';
14+
if (preg_match($regexp, $str, $match)) {
15+
assertType('array{string, string}', $match);
16+
}
17+
}

0 commit comments

Comments
 (0)