@@ -67,9 +67,9 @@ public function parseGroups(string $regex): ?array
67
67
}
68
68
69
69
$ captureOnlyNamed = false ;
70
+ $ modifiers = $ this ->regexExpressionHelper ->getPatternModifiers ($ regex ) ?? '' ;
70
71
if ($ this ->phpVersion ->supportsPregCaptureOnlyNamedGroups ()) {
71
- $ modifiers = $ this ->regexExpressionHelper ->getPatternModifiers ($ regex );
72
- $ captureOnlyNamed = str_contains ($ modifiers ?? '' , 'n ' );
72
+ $ captureOnlyNamed = str_contains ($ modifiers , 'n ' );
73
73
}
74
74
75
75
$ capturingGroups = [];
@@ -90,6 +90,7 @@ public function parseGroups(string $regex): ?array
90
90
$ markVerbs ,
91
91
$ captureOnlyNamed ,
92
92
false ,
93
+ $ modifiers ,
93
94
);
94
95
95
96
return [$ capturingGroups , $ groupCombinations , $ markVerbs ];
@@ -113,38 +114,29 @@ private function walkRegexAst(
113
114
array &$ markVerbs ,
114
115
bool $ captureOnlyNamed ,
115
116
bool $ repeatedMoreThanOnce ,
117
+ string $ patternModifiers ,
116
118
): void
117
119
{
118
120
$ group = null ;
119
121
if ($ ast ->getId () === '#capturing ' ) {
120
- $ maybeConstant = !$ repeatedMoreThanOnce ;
121
- if ($ parentGroup !== null && $ parentGroup ->resetsGroupCounter ()) {
122
- $ maybeConstant = false ;
123
- }
124
-
125
122
$ group = new RegexCapturingGroup (
126
123
$ captureGroupId ++,
127
124
null ,
128
125
$ inAlternation ? $ alternationId : null ,
129
126
$ inOptionalQuantification ,
130
127
$ parentGroup ,
131
- $ this ->createGroupType ($ ast , $ maybeConstant ),
128
+ $ this ->createGroupType ($ ast , $ this -> allowConstantTypes ( $ patternModifiers , $ repeatedMoreThanOnce , $ parentGroup ) ),
132
129
);
133
130
$ parentGroup = $ group ;
134
131
} elseif ($ ast ->getId () === '#namedcapturing ' ) {
135
- $ maybeConstant = !$ repeatedMoreThanOnce ;
136
- if ($ parentGroup !== null && $ parentGroup ->resetsGroupCounter ()) {
137
- $ maybeConstant = false ;
138
- }
139
-
140
132
$ name = $ ast ->getChild (0 )->getValueValue ();
141
133
$ group = new RegexCapturingGroup (
142
134
$ captureGroupId ++,
143
135
$ name ,
144
136
$ inAlternation ? $ alternationId : null ,
145
137
$ inOptionalQuantification ,
146
138
$ parentGroup ,
147
- $ this ->createGroupType ($ ast , $ maybeConstant ),
139
+ $ this ->createGroupType ($ ast , $ this -> allowConstantTypes ( $ patternModifiers , $ repeatedMoreThanOnce , $ parentGroup ) ),
148
140
);
149
141
$ parentGroup = $ group ;
150
142
} elseif ($ ast ->getId () === '#noncapturing ' ) {
@@ -217,6 +209,7 @@ private function walkRegexAst(
217
209
$ markVerbs ,
218
210
$ captureOnlyNamed ,
219
211
$ repeatedMoreThanOnce ,
212
+ $ patternModifiers ,
220
213
);
221
214
222
215
if ($ ast ->getId () !== '#alternation ' ) {
@@ -227,6 +220,29 @@ private function walkRegexAst(
227
220
}
228
221
}
229
222
223
+ private function allowConstantTypes (
224
+ string $ patternModifiers ,
225
+ bool $ repeatedMoreThanOnce ,
226
+ RegexCapturingGroup |RegexNonCapturingGroup |null $ parentGroup ,
227
+ ): bool
228
+ {
229
+ if (str_contains ($ patternModifiers , 'i ' )) {
230
+ // if caseless, we don't use constant types
231
+ // because it likely yields too many combinations
232
+ return false ;
233
+ }
234
+
235
+ if ($ repeatedMoreThanOnce ) {
236
+ return false ;
237
+ }
238
+
239
+ if ($ parentGroup !== null && $ parentGroup ->resetsGroupCounter ()) {
240
+ return false ;
241
+ }
242
+
243
+ return true ;
244
+ }
245
+
230
246
/** @return array{?int, ?int} */
231
247
private function getQuantificationRange (TreeNode $ node ): array
232
248
{
0 commit comments