From 101996d9ac64ef1d66a630223cd82451dc930900 Mon Sep 17 00:00:00 2001 From: Wondr Date: Thu, 4 Jun 2026 23:13:39 +0100 Subject: [PATCH] grep: honor GNU buffer anchors in BRE --- src/matcher.rs | 4 ++++ tests/test_grep.rs | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/matcher.rs b/src/matcher.rs index d9cf846..c1be567 100644 --- a/src/matcher.rs +++ b/src/matcher.rs @@ -215,6 +215,10 @@ impl CompiledPattern { // GNU grep supports `{,n}` as an alias for `{0,n}`. syntax.enable_behavior(SyntaxBehavior::SYNTAX_BEHAVIOR_ALLOW_INTERVAL_LOW_ABBREV); } + if config.regex_mode == RegexMode::Basic { + // GNU grep treats \` and \' as buffer anchors. + syntax.enable_operators(SyntaxOperator::SYNTAX_OPERATOR_ESC_GNU_BUF_ANCHOR); + } if config.regex_mode == RegexMode::Perl { // GNU grep supports `(?P...)`. // Unfortunately, the onig crate defines the OP2 flag without the diff --git a/tests/test_grep.rs b/tests/test_grep.rs index d061918..79dc9a8 100644 --- a/tests/test_grep.rs +++ b/tests/test_grep.rs @@ -70,6 +70,18 @@ fn bre_gnu_extensions() { .succeeds() .stdout_only("contain\n"); + let (_s, mut c) = ucmd(); + c.args(&[r"\`c"]) + .pipe_in("cat\nscat\n") + .succeeds() + .stdout_only("cat\n"); + + let (_s, mut c) = ucmd(); + c.args(&[r"t\'"]) + .pipe_in("cat\ntab\n") + .succeeds() + .stdout_only("cat\n"); + // BRE backreference: repeated adjacent word. let (_s, mut c) = ucmd(); c.args(&[r"\(\b\w\+\b\) \1"])