regex之在已编译的正则表达式中禁用捕获 (例如,Perl 5.22+,/n 修饰符)

zhengyun_ustc 阅读:202 2025-06-02 22:19:02 评论:0

环境:Cygwin x64 上的 Perl 5.26.2 x64。

问题:my $re = qr/...(capturing group).../之后,有没有办法使用$re 没有捕获到它的捕获组中?

X: 我匹配的行可能是:

#define FOO(X,Y) SomeComplicatedStuff 

#define FOO(X,Y) BAR(X,Y) 

我有一个已编译的正则表达式 $re 匹配 FOO(X,Y) 并包含编号的捕获组以将匹配拆分为 FOOX,Y。我想匹配第二种形式的行,而不必定义单独的正则表达式,例如,使用 m/$re.+$re/。这工作正常,但是当我真正想要的是 BAR 组时,我得到了 FOO 的所有捕获组。

Y: 我认为我可以在 5.22+ 中使用 /n 修饰符来做到这一点,但我无法让它工作。 MCVE:

$ perl -E 'my $re=qr/(foo|bar)/; "foobar" =~ m/$re$re/; say $1, " ", $2;' 
foo bar     # as expected 
 
$ perl -E 'my $re=qr/(foo|bar)/; "foobar" =~ m/(?n:$re)$re/; say $1, " ", $2;' 
            # I think this should turn off      ^^^  capturing of `foo` 
foo bar     # oops - I was hoping for `bar` 
 
$ perl -E 'my $re=qr/(foo|bar)/; "foobar" =~ m/(?n:(foo|bar))$re/; say $1, " ", $2;' 
bar         # This works, but I had to inline $re within (?n:...). 

注意:我也试过\K:

$ perl -E 'my $re=qr/(foo|bar)/; "foobar" =~ m/$re\K$re/; say $1, " ", $2, " ", $&;' 
foo bar bar      # was hoping for `bar  bar` 

编辑 忘了说了——我看过this related question ,但这不是同一个问题陈述。

请您参考如下方法:

$re的字符串化为(?^u:(foo|bar))。换句话说,它将标志设置为编译模式时使用的标志,从而关闭 /n

您可以使用以下任何一种:

my $re = qq/(foo|bar)/;    # Note: Gotta escape `\` that are part of regex escapes. 
/(?n:$re)$re/ 

(转义示例:qr{(fo\w|ba\w)} 变为 qq{(fo\\w|ba\\w)} 时使用这种技术。)

my $re = qr/foo|bar/; 
/$re($re)/ 

my $re = qr/ 
   (?<foo_or_bar>) ((?<foo_or_bar>)) 
   (?(DEFINE) 
      (?<foo_or_bar>foo|bar) 
   ) 
/x; 
/$re/ 


声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号