Skip to content

Commit c053dbc

Browse files
authored
Support # comments in regex with x modifier
1 parent 73d0f13 commit c053dbc

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

src/Type/Regex/RegexGroupParser.php

+13-7
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,25 @@ 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+
if (str_contains($modifiers, 'x')) {
76+
// in freespacing mode the # character starts a comment and runs until the end of the line
77+
$regex = preg_replace('/[^?]#.*/', '', $regex) ?? '';
78+
}
79+
80+
$rawRegex = $this->regexExpressionHelper->removeDelimitersAndModifiers($regex);
81+
try {
82+
$ast = self::$parser->parse($rawRegex);
83+
} catch (Exception) {
84+
return null;
85+
}
86+
8187
$captureOnlyNamed = false;
8288
if ($this->phpVersion->supportsPregCaptureOnlyNamedGroups()) {
8389
$captureOnlyNamed = str_contains($modifiers, 'n');
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
}
18+
19+
function bar(string $str): void
20+
{
21+
$regexp = '/^
22+
(\w+) # column type [1]
23+
[\(] # (
24+
?([\d,]*) # size or size, precision [2]
25+
[\)] # )
26+
?\s* # whitespace
27+
(\w*) # extra description (UNSIGNED, CHARACTER SET, ...) [3]
28+
$/x';
29+
if (preg_match($regexp, $str, $matches)) {
30+
assertType('array{string, non-empty-string, string, string}', $matches);
31+
}
32+
}

0 commit comments

Comments
 (0)