Skip to content

Commit f664578

Browse files
committed
expr: Handle special cases for ^ in regex
1 parent 6a828f0 commit f664578

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

src/uu/expr/src/syntax_tree.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,18 @@ impl StringOp {
171171
let mut prev_is_escaped = false;
172172
for curr in pattern_chars {
173173
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"\^");
174+
'^' => match (prev, prev_is_escaped) {
175+
// Start of a capturing group
176+
('(', true)
177+
// Start of an alternative pattern
178+
| ('|', true)
179+
// Character class negation "[^a]"
180+
| ('[', false)
181+
// Explicitly escaped caret
182+
| ('\\', false) => re_string.push(curr),
183+
_ => re_string.push_str(r"\^"),
177184
}
178-
char => re_string.push(char),
185+
_ => re_string.push(curr),
179186
}
180187

181188
prev_is_escaped = prev == '\\' && !prev_is_escaped;

tests/by-util/test_expr.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,14 @@ fn test_regex() {
282282
.args(&["a^b", ":", "a\\^b"])
283283
.succeeds()
284284
.stdout_only("3\n");
285+
new_ucmd!()
286+
.args(&["b", ":", "a\\|^b"])
287+
.succeeds()
288+
.stdout_only("1\n");
289+
new_ucmd!()
290+
.args(&["ab", ":", "\\(^a\\)b"])
291+
.succeeds()
292+
.stdout_only("a\n");
285293
new_ucmd!()
286294
.args(&["a$b", ":", "a\\$b"])
287295
.succeeds()

0 commit comments

Comments
 (0)