如何在Perl中捕获所有量化的正则表达式匹配?

时间:2014-05-05 11:45:19

标签: perl

如果regex是正则表达式,我可以捕获它的两次重复:

if (/(regex)(regex)/) {
    print $1;
    print $2;
}

但这是糟糕的Perl,因为它应该使用{2}量词,以及糟糕的通用编程风格,因为它重复代码。所以我想这样做:

if (/(regex){2}/) {
    print $1;
    print $2;
}

但这不起作用,只打印第一场比赛。

有没有办法打印两个匹配而不重复代码?

4 个答案:

答案 0 :(得分:3)

您需要在整个表达式周围添加括号,包括量词,如/((regex){2})/。但是,由于不需要内部捕获,因此最好使用非捕获括号(?: ... ),以便您的代码看起来像

if ( /((?:regex){2})/ ) {
  print $1;
}

答案 1 :(得分:1)

你到底想要达到什么目的?您可以打印匹配的整个部分:

if (/((regex){2})/) {
    print $1;
}

或者您可以尝试与while/g多次匹配。 \G将确保比赛之间没有任何字符。

while (/\G(regex)/g) {
    print $1;
}

答案 2 :(得分:1)

  

我想在Perl中多次匹配正则表达式并打印所有匹配

这不是你的计划正在做什么。你的程序正在做的是regex,它必须连续两次。 {..}用于指定您想要的次数:

if ( $string =~ /a{2,3}/ ) {
     say "The string '$string' has two or three 'a' in a row";
}

然而,您似乎要求的是所有时间$regex出现在字符串中。您可以将匹配项保存在这样的数组中:

my $string = "barfaafeebarbarfiifoo";
my @matches = ( $string =~ /f../g );
for my $match ( @matches ) { 
    say "$match";
}

这将打印出来:

faa
fee
fii
foo

如果与正则表达式/f../没有匹配,则不打印任何内容。我可以通过查看@matches的标量值并查看它是否大于零来测试匹配是否发生。

请注意,在这种情况下,我需要在正则表达式结尾处使用g

答案 3 :(得分:-2)

如果你不关心哪一个匹配,你可以用这种方式连接多个正则表达式:

if ( $s =~ m!(regexp1|regexp2|regexp3)! ){
  print "found $1\n";
}

如果你关心哪一个匹配,我会这样做:

foreach my $r ( 'regexp1','regexp2'){
    if ( $s =~ m!$r! ){
      print "$r matched: found $1 in $s\n";
    }
}