@@ -11,6 +11,7 @@ use onig::{
1111} ;
1212use onig_sys:: { OnigEncCtype_ONIGENC_CTYPE_WORD , OnigEncodingUTF8 } ;
1313use uucore:: error:: { UResult , USimpleError } ;
14+ use uucore:: show_warning;
1415
1516pub struct Matcher < ' a > {
1617 config : & ' a Config < ' a > ,
@@ -273,6 +274,18 @@ impl CompiledPattern {
273274 // GNU grep supports \` and \' as buffer anchors in BRE and ERE.
274275 syntax. enable_operators ( SyntaxOperator :: SYNTAX_OPERATOR_ESC_GNU_BUF_ANCHOR ) ;
275276 }
277+
278+ let mut normalized_pattern = None ;
279+ let pattern = if config. regex_mode == RegexMode :: Extended {
280+ if let Some ( ( op, rest) ) = strip_leading_repeat_operator ( pattern) {
281+ show_warning ! ( "{op} at start of expression" ) ;
282+ normalized_pattern = Some ( rest. to_string ( ) ) ;
283+ }
284+ normalized_pattern. as_deref ( ) . unwrap_or ( pattern)
285+ } else {
286+ pattern
287+ } ;
288+
276289 if config. regex_mode == RegexMode :: Perl {
277290 // GNU grep supports `(?P<name>...)`.
278291 // Unfortunately, the onig crate defines the OP2 flag without the
@@ -354,6 +367,25 @@ impl CompiledPattern {
354367 }
355368}
356369
370+ fn strip_leading_repeat_operator ( pattern : & str ) -> Option < ( & ' static str , & str ) > {
371+ match pattern. as_bytes ( ) . first ( ) ? {
372+ b'?' => Some ( ( "?" , & pattern[ 1 ..] ) ) ,
373+ b'*' => Some ( ( "*" , & pattern[ 1 ..] ) ) ,
374+ b'+' => Some ( ( "+" , & pattern[ 1 ..] ) ) ,
375+ b'{' => strip_leading_interval_repeat ( pattern) . map ( |rest| ( "{...}" , rest) ) ,
376+ _ => None ,
377+ }
378+ }
379+
380+ fn strip_leading_interval_repeat ( pattern : & str ) -> Option < & str > {
381+ let close = pattern. as_bytes ( ) . iter ( ) . position ( |& b| b == b'}' ) ?;
382+ let body = & pattern[ 1 ..close] ;
383+ let is_interval = !body. is_empty ( )
384+ && body. bytes ( ) . all ( |b| b. is_ascii_digit ( ) || b == b',' )
385+ && body. bytes ( ) . any ( |b| b. is_ascii_digit ( ) ) ;
386+ is_interval. then_some ( & pattern[ close + 1 ..] )
387+ }
388+
357389#[ cfg( test) ]
358390mod tests {
359391 use super :: plain_literal;
0 commit comments