77use Nette \Utils \Strings ;
88use PhpParser \Node \Expr ;
99use PhpParser \Node \Expr \BinaryOp \Concat ;
10+ use PhpParser \Node \InterpolatedStringPart ;
11+ use PhpParser \Node \Scalar \InterpolatedString ;
1012use PhpParser \Node \Scalar \String_ ;
1113
1214final readonly class RegexMatcher
2729 */
2830 private const array ALL_MODIFIERS_VALUES = ['i ' , 'm ' , 's ' , 'x ' , 'e ' , 'A ' , 'D ' , 'S ' , 'U ' , 'X ' , 'J ' , 'u ' ];
2931
30- public function resolvePatternExpressionWithoutEIfFound (Expr $ expr ): Concat |String_ |null
32+ public function resolvePatternExpressionWithoutEIfFound (Expr $ expr ): Concat |String_ |InterpolatedString | null
3133 {
3234 if ($ expr instanceof String_) {
3335 $ pattern = $ expr ->value ;
34-
35- $ delimiter = $ pattern [0 ];
36- $ delimiter = match ($ delimiter ) {
37- '( ' => ') ' ,
38- '{ ' => '} ' ,
39- '[ ' => '] ' ,
40- '< ' => '> ' ,
41- default => $ delimiter
42- };
36+ $ delimiter = $ this ->resolveClosingDelimiter ($ pattern );
4337
4438 $ modifiers = $ this ->resolveModifiers ((string ) Strings ::after ($ pattern , $ delimiter , -1 ));
4539 if (! \str_contains ($ modifiers , 'e ' )) {
@@ -55,9 +49,50 @@ public function resolvePatternExpressionWithoutEIfFound(Expr $expr): Concat|Stri
5549 return $ this ->matchConcat ($ expr );
5650 }
5751
52+ if ($ expr instanceof InterpolatedString) {
53+ return $ this ->matchInterpolatedString ($ expr );
54+ }
55+
5856 return null ;
5957 }
6058
59+ private function resolveClosingDelimiter (string $ pattern ): string
60+ {
61+ $ delimiter = $ pattern [0 ];
62+ return match ($ delimiter ) {
63+ '( ' => ') ' ,
64+ '{ ' => '} ' ,
65+ '[ ' => '] ' ,
66+ '< ' => '> ' ,
67+ default => $ delimiter
68+ };
69+ }
70+
71+ private function matchInterpolatedString (InterpolatedString $ interpolatedString ): ?InterpolatedString
72+ {
73+ $ firstPart = $ interpolatedString ->parts [0 ] ?? null ;
74+ if (! $ firstPart instanceof InterpolatedStringPart) {
75+ return null ;
76+ }
77+
78+ $ lastPart = $ interpolatedString ->parts [array_key_last ($ interpolatedString ->parts )];
79+ if (! $ lastPart instanceof InterpolatedStringPart) {
80+ return null ;
81+ }
82+
83+ $ delimiter = $ this ->resolveClosingDelimiter ($ firstPart ->value );
84+ $ pattern = $ lastPart ->value ;
85+
86+ $ modifiers = $ this ->resolveModifiers ((string ) Strings ::after ($ pattern , $ delimiter , -1 ));
87+ if (! \str_contains ($ modifiers , 'e ' )) {
88+ return null ;
89+ }
90+
91+ $ lastPart ->value = $ this ->createPatternWithoutE ($ pattern , $ delimiter , $ modifiers );
92+
93+ return $ interpolatedString ;
94+ }
95+
6196 private function resolveModifiers (string $ modifiersCandidate ): string
6297 {
6398 $ modifiers = '' ;
0 commit comments