From 05d167b8d569d13f0fda42076b897798c860a152 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Fri, 29 May 2026 21:12:19 +0200 Subject: [PATCH] Fix support for Python-style named backreferences --- src/matcher.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/matcher.rs b/src/matcher.rs index 5d68996..d9cf846 100644 --- a/src/matcher.rs +++ b/src/matcher.rs @@ -4,7 +4,10 @@ // file that was distributed with this source code. use crate::{Config, RegexMode}; -use onig::{EncodedBytes, Regex, RegexOptions, Region, SearchOptions, Syntax, SyntaxBehavior}; +use onig::{ + EncodedBytes, Regex, RegexOptions, Region, SearchOptions, Syntax, SyntaxBehavior, + SyntaxOperator, +}; use onig_sys::{OnigEncCtype_ONIGENC_CTYPE_WORD, OnigEncodingUTF8}; use uucore::error::{UResult, USimpleError}; @@ -206,11 +209,23 @@ impl CompiledPattern { RegexMode::Fixed => Syntax::asis(), RegexMode::Basic => Syntax::grep(), RegexMode::Extended => Syntax::gnu_regex(), - RegexMode::Perl => Syntax::perl(), + RegexMode::Perl => Syntax::perl_ng(), }; - if !matches!(config.regex_mode, RegexMode::Fixed) { + if config.regex_mode != RegexMode::Fixed { + // 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::Perl { + // GNU grep supports `(?P...)`. + // Unfortunately, the onig crate defines the OP2 flag without the + // necessary <<32 bit shift, so we need to hotpatch that here. + const _: () = + assert!(SyntaxOperator::SYNTAX_OPERATOR_QMARK_CAPITAL_P_NAME.bits() == 0x80000000); + const FIXED: SyntaxOperator = SyntaxOperator::from_bits_retain( + SyntaxOperator::SYNTAX_OPERATOR_QMARK_CAPITAL_P_NAME.bits() << 32, + ); + syntax.enable_operators(FIXED); + } let mut options = RegexOptions::REGEX_OPTION_NONE; if config.ignore_case {