环境: 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)
匹配,并包括编号的捕获组,以将匹配项分为FOO
和X,Y
。我想匹配第二种形式的行而不必定义单独的正则表达式,例如,使用m/$re.+$re/
。效果很好,但是当我真正想要的是FOO
的组时,我得到了BAR
的所有捕获组。
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,但这不是相同的问题说明。
答案 0 :(得分:3)
$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)
好吧,我找到了解决方法,但这当然不是答案!无论如何,我都会在这里发布,以防其他人使用。在我的特定用例中,匹配项分为两部分。因此,在第一场比赛中使用/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!