diff --git a/brush-core/src/patterns.rs b/brush-core/src/patterns.rs index c636cfba..36913abb 100644 --- a/brush-core/src/patterns.rs +++ b/brush-core/src/patterns.rs @@ -297,25 +297,17 @@ impl Pattern { current_pattern.push_str(s); } PatternPiece::Literal(s) => { - if !current_pattern.is_empty() { - let regex_piece = pattern_to_regex_str( - current_pattern.as_str(), - self.enable_extended_globbing, - )?; - regex_str.push_str(regex_piece.as_str()); - current_pattern = String::new(); + for c in s.chars() { + current_pattern.push('\\'); + current_pattern.push(c); } - - regex_str.push_str(escape_for_regex(s).as_str()); } } } - if !current_pattern.is_empty() { - let regex_piece = - pattern_to_regex_str(current_pattern.as_str(), self.enable_extended_globbing)?; - regex_str.push_str(regex_piece.as_str()); - } + let regex_piece = + pattern_to_regex_str(current_pattern.as_str(), self.enable_extended_globbing)?; + regex_str.push_str(regex_piece.as_str()); if strict_suffix_match { regex_str.push('$'); @@ -361,26 +353,10 @@ fn requires_expansion(s: &str) -> bool { s.contains(['*', '?', '[', ']', '(', ')']) } -fn escape_for_regex(s: &str) -> String { - let mut escaped = String::new(); - for c in s.chars() { - if brush_parser::pattern::regex_char_needs_escaping(c) { - escaped.push('\\'); - } - escaped.push(c); - } - escaped -} - fn pattern_to_regex_str( pattern: &str, enable_extended_globbing: bool, ) -> Result { - // TODO: pattern matching with ** - if pattern.contains("**") { - return error::unimp("pattern matching with '**' pattern"); - } - Ok(brush_parser::pattern::pattern_to_regex_str( pattern, enable_extended_globbing, diff --git a/brush-parser/src/pattern.rs b/brush-parser/src/pattern.rs index 39d277a0..b8803b62 100644 --- a/brush-parser/src/pattern.rs +++ b/brush-parser/src/pattern.rs @@ -155,6 +155,18 @@ mod tests { use super::*; use anyhow::Result; + #[test] + fn test_bracket_exprs() -> Result<()> { + assert_eq!(pattern_to_regex_str("[a-z]", true)?, "[a-z]"); + assert_eq!(pattern_to_regex_str("[abc]", true)?, "[abc]"); + assert_eq!(pattern_to_regex_str(r"[\(]", true)?, r"[\(]"); + assert_eq!(pattern_to_regex_str(r"[(]", true)?, "[(]"); + assert_eq!(pattern_to_regex_str("[[:digit:]]", true)?, "[[:digit:]]"); + assert_eq!(pattern_to_regex_str(r"[-(),!]*", true)?, r"[-(),!].*"); + assert_eq!(pattern_to_regex_str(r"[-\(\),\!]*", true)?, r"[-\(\),\!].*"); + Ok(()) + } + #[test] fn test_extended_glob() -> Result<()> { assert_eq!( diff --git a/brush-shell/tests/cases/patterns.yaml b/brush-shell/tests/cases/patterns.yaml index 2f7790c1..a049fb4c 100644 --- a/brush-shell/tests/cases/patterns.yaml +++ b/brush-shell/tests/cases/patterns.yaml @@ -267,3 +267,10 @@ cases: myfunc abc myfunc "*" + + - name: "Pattern matching: character sets" + stdin: | + [[ "x" == [a-z] ]] && echo "1. Matched" + [[ "x" == [xyz] ]] && echo "2. Matched" + [[ "1" == [[:digit:]] ]] && echo "3. Matched" + [[ "(" == [\(] ]] && echo "4. Matched"