@@ -156,7 +156,7 @@ impl StringOp {
156156 re_string. push ( '^' ) ;
157157
158158 // Handle first character from the input pattern
159- let mut pattern_chars = right. chars ( ) ;
159+ let mut pattern_chars = right. chars ( ) . peekable ( ) ;
160160 let first = pattern_chars. next ( ) ;
161161 match first {
162162 Some ( '^' ) => { } // Start of string anchor is already added
@@ -166,16 +166,42 @@ impl StringOp {
166166 } ;
167167
168168 // Handle the rest of the input pattern.
169- // Escaped previous character should not affect the current.
170169 let mut prev = first. unwrap_or_default ( ) ;
171170 let mut prev_is_escaped = false ;
172- for curr in pattern_chars {
171+ while let Some ( curr) = pattern_chars. next ( ) {
173172 match curr {
174- // Carets are interpreted literally, unless used as character class negation "[^a]"
175- '^' if prev_is_escaped || !matches ! ( prev, '\\' | '[' ) => {
176- re_string. push_str ( r"\^" ) ;
173+ '^' => match ( prev, prev_is_escaped) {
174+ // Start of a capturing group
175+ ( '(' , true )
176+ // Start of an alternative pattern
177+ | ( '|' , true )
178+ // Character class negation "[^a]"
179+ | ( '[' , false )
180+ // Explicitly escaped caret
181+ | ( '\\' , false ) => re_string. push ( curr) ,
182+ _ => re_string. push_str ( r"\^" ) ,
183+ } ,
184+ '$' => {
185+ if let Some ( '\\' ) = pattern_chars. peek ( ) {
186+ // The next character was checked to be a backslash
187+ let backslash = pattern_chars. next ( ) . unwrap_or_default ( ) ;
188+ match pattern_chars. peek ( ) {
189+ // End of a capturing group
190+ Some ( ')' ) => re_string. push ( '$' ) ,
191+ // End of an alternative pattern
192+ Some ( '|' ) => re_string. push ( '$' ) ,
193+ _ => re_string. push_str ( r"\$" ) ,
194+ }
195+ re_string. push ( backslash) ;
196+ } else if ( prev_is_escaped || prev != '\\' )
197+ && pattern_chars. peek ( ) . is_some ( )
198+ {
199+ re_string. push_str ( r"\$" ) ;
200+ } else {
201+ re_string. push ( '$' ) ;
202+ }
177203 }
178- char => re_string. push ( char ) ,
204+ _ => re_string. push ( curr ) ,
179205 }
180206
181207 prev_is_escaped = prev == '\\' && !prev_is_escaped;
0 commit comments