【问题标题】:How can I know which portion of a Perl regex is matched by a string?我如何知道 Perl 正则表达式的哪一部分与字符串匹配?
【发布时间】:2011-07-15 00:18:42
【问题描述】:

我想搜索一个文件的行,看看它们是否与一组正则表达式中的一个匹配。

类似这样的:

my @regs = (qr/a/, qr/b/, qr/c/);
foreach my $line (<ARGV>) {
   foreach my $reg (@regs) {
      if ($line =~ /$reg/) {
         printf("matched %s\n", $reg);
      }
   }
}

但这可能会很慢。

似乎正则表达式编译器可以提供帮助。有没有这样的优化:

my $master_reg = join("|", @regs); # this is wrong syntax. what's the right way?
foreach my $line (<ARGV>) {
   $line =~ /$master_reg/;
   my $matched = special_function();
   printf("matched the %sth reg: %s\n", $matched, $regs[$matched]
}

}

'special_function' 是特殊的调味汁,告诉我正则表达式的哪个部分匹配。

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    使用捕获括号。基本思路如下:

    my @matches = $foo =~ /(one)|(two)|(three)/;
    defined $matches[0]
        and print "Matched 'one'\n";
    defined $matches[1]
        and print "Matched 'two'\n";
    defined $matches[2]
        and print "Matched 'three'\n";
    

    【讨论】:

      【解决方案2】:

      添加捕获组:

      "pear" =~ /(a)|(b)|(c)/;
      if (defined $1) {
          print "Matched a\n";
      } elsif (defined $2) {
          print "Matched b\n";
      } elsif (defined $3) {
          print "Matched c\n";
      } else {
          print "No match\n";
      }
      

      显然,在这个简单的示例中,您也可以使用 /(a|b|c)/ 并打印 $1,但是当 'a'、'b' 和 'c' 可以是任意复杂的表达式时,这是一个胜利。

      如果您以编程方式构建正则表达式,您可能会发现必须使用编号变量很痛苦,因此不要打破严格性,而是查看 @-@+ 数组,其中包含每个匹配项的偏移量位置。只要模式完全匹配,$-[0] 就会一直设置,但如果nth 捕获组匹配,则更高的$-[$n] 将只包含定义的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-25
        • 1970-01-01
        • 1970-01-01
        • 2014-09-09
        • 2010-09-15
        相关资源
        最近更新 更多