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



环境:Perl 5.26.2 x64 on Cygwin 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:我以为我可以用/n修饰符在 5.22+ 中做到这一点,但我无法让它工作。 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/$reK$re/; say $1, " ", $2, " ", $&;'
foo bar bar      # was hoping for `bar  bar`

编辑忘了提 — 我确实看过这个相关问题,但它不是同一个问题陈述。

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

您可以使用以下任一方法:

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

(转义示例:使用此技术时,qr{(fow|baw)}变得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/

好吧,我找到了解决方法,但这肯定不是答案! 无论如何,我都会在这里发布它,以防它对其他人有所帮助。 在我的特定用例中,匹配被一分为二。 因此,在第一场比赛中使用/g,在第二场比赛中使用G就可以解决问题。 例:

$ perl -E '
my $re=qr/(foo|bar)/;
my $str = "foo bar";
$str =~ m/$re/g;         # Match `foo`, and set `pos` (because of /g)
say "Expecting foo: ", $1;
$str =~ m/G.+$re/g;     # G => skip past `foo`, and check ` bar` against `.+$re`
say "Hoping for bar: ";
'
Expecting foo: foo
Hoping for bar: bar          # Hooray!

最新更新