mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 03:57:44 +00:00
expr: Only '^' requires special treatment at the start of regex
This commit is contained in:
parent
210f4f7154
commit
ca6a10ea9a
1 changed files with 13 additions and 17 deletions
|
@ -151,27 +151,21 @@ impl StringOp {
|
||||||
let right = right?.eval_as_string();
|
let right = right?.eval_as_string();
|
||||||
check_posix_regex_errors(&right)?;
|
check_posix_regex_errors(&right)?;
|
||||||
|
|
||||||
// All patterns are anchored so they begin with a caret (^)
|
// Transpile the input pattern from BRE syntax to `onig` crate's `Syntax::grep`
|
||||||
let mut re_string = String::with_capacity(right.len() + 1);
|
let mut re_string = String::with_capacity(right.len() + 1);
|
||||||
re_string.push('^');
|
|
||||||
|
|
||||||
// Handle first character from the input pattern
|
|
||||||
let mut pattern_chars = right.chars().peekable();
|
let mut pattern_chars = right.chars().peekable();
|
||||||
let first = pattern_chars.next();
|
let mut prev = '\0';
|
||||||
match first {
|
|
||||||
Some('^') => {} // Start of string anchor is already added
|
|
||||||
Some('$') if !is_end_of_expression(&pattern_chars) => re_string.push_str(r"\$"),
|
|
||||||
Some('\\') if right.len() == 1 => return Err(ExprError::TrailingBackslash),
|
|
||||||
Some(char) => re_string.push(char),
|
|
||||||
None => return Ok(0.into()),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle the rest of the input pattern.
|
|
||||||
let mut prev = first.unwrap_or_default();
|
|
||||||
let mut prev_is_escaped = false;
|
let mut prev_is_escaped = false;
|
||||||
let mut is_start_of_expression = first == Some('\\');
|
let mut is_start_of_expression = true;
|
||||||
|
|
||||||
|
// All patterns are anchored so they begin with a caret (^)
|
||||||
|
if pattern_chars.peek() != Some(&'^') {
|
||||||
|
re_string.push('^');
|
||||||
|
}
|
||||||
|
|
||||||
while let Some(curr) = pattern_chars.next() {
|
while let Some(curr) = pattern_chars.next() {
|
||||||
let curr_is_escaped = prev == '\\' && !prev_is_escaped;
|
let curr_is_escaped = prev == '\\' && !prev_is_escaped;
|
||||||
|
let is_first_character = prev == '\0';
|
||||||
|
|
||||||
match curr {
|
match curr {
|
||||||
// Character class negation "[^a]"
|
// Character class negation "[^a]"
|
||||||
|
@ -208,8 +202,10 @@ impl StringOp {
|
||||||
|
|
||||||
// Capturing group "\(abc\)"
|
// Capturing group "\(abc\)"
|
||||||
// Alternative pattern "a\|b"
|
// Alternative pattern "a\|b"
|
||||||
is_start_of_expression = curr_is_escaped && matches!(curr, '(' | '|')
|
is_start_of_expression = curr == '\\' && is_first_character
|
||||||
|
|| curr_is_escaped && matches!(curr, '(' | '|')
|
||||||
|| curr == '\\' && prev_is_escaped && matches!(prev, '(' | '|');
|
|| curr == '\\' && prev_is_escaped && matches!(prev, '(' | '|');
|
||||||
|
|
||||||
prev_is_escaped = curr_is_escaped;
|
prev_is_escaped = curr_is_escaped;
|
||||||
prev = curr;
|
prev = curr;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue