【问题标题】:How do I access captured substrings after a successful regex match in Perl?在 Perl 中成功匹配正则表达式后,如何访问捕获的子字符串?
【发布时间】:2009-06-24 22:47:08
【问题描述】:

我正在 Perl 中搜索一个字符串并将其存储在另一个标量变量中。我想打印这个标量变量。下面的代码似乎不起作用。我不确定出了什么问题以及解决问题的正确方法是什么。为什么在程序中不存在时打印'1'?

它正在运行的数据

数据

      13 E 0.496 -> Q 0.724
      18 S 0.507 -> R 0.513
      19 N 0.485 -> S 0.681
      21 N 0.557 -> K 0.482

以下是我的代码:

#!/usr/bin/perl
use strict;
use warnings;

my $find = '\s{10}[0-9]{2}\s[A-Z]'; #regex. it can also be '\s{10}[0-9]{2}\s[A-Z]' 
                                    #both dont seem to work
my @element;
open (FILE, "/user/run/test") || die "can't open file \n";
while (my $line = <FILE>) {
    chomp ($line);
    print "reached here1 \n"; # to test whether it reading the program properly
    my $value = $line=~ /$find/ ;
    print "reached here 3 \n"; # to test whether it reading the program properly
    print "$value \n";
}
exit;

输出

reached here1

1 

reached here 3 

reached here1 

1 

reached here 3 

【问题讨论】:

标签: regex perl


【解决方案1】:

正则表达式匹配操作返回 true (1) 表示匹配成功,否则返回 false。如果您想检索匹配项,您应该尝试以下方法之一:

  • 使用匹配变量 $1, $2...
  • 匹配列表上下文($m1, $m2) = $string =~ /$regex/

请注意,您需要在正则表达式中使用捕获才能使这些工作。你还没有做。

您应该查看perlop 中的完整文档,“Regexp Quote-Like Operators”部分

【讨论】:

    【解决方案2】:

    JB 是正确的。您的正则表达式需要对要收集的各个部分使用捕获(由括号定义)。如果你想捕获你的行中的所有元素,你会想要这个:

    my $find = '\s{10}([0-9]{2})\s([A-Z])';
    my $field1;
    my $field2;
    while (my $line = <FILE>) {
       chomp ($line);
       if ($line=~ /$find/) {
          $field1 = $1;
          $field2 = $2;
          # Do something with current line's field 1 and field 2
       }
    }
    

    【讨论】:

      【解决方案3】:

      m// 在列表上下文中返回捕获的匹配项:

      #!/usr/bin/perl
      
      use strict;
      use warnings;
      
      my $pattern = qr/^\s{10}([0-9]{2})\s[A-Z]/;
      
      while ( my $line = <DATA> ) {
          if ( my ($n) = $line =~ $pattern ) {
              print "$n\n";
          }
      }
      
      __DATA__
                13 E 0.496 -> Q 0.724
                18 S 0.507 -> R 0.513
                19 N 0.485 -> S 0.681
                21 N 0.557 -> K 0.482
      

      【讨论】:

        【解决方案4】:

        我无法复制您的结果。我得到的是:

        reached here1 
        reached here 3 
        1 
        reached here1 
        reached here 3 
        1 
        reached here1 
        reached here 3 
        1 
        reached here1 
        reached here 3 
        1 
        

        不管怎样,它打印 1 是因为你告诉它这样做:打印语句是在 while 循环内,它打印的内容是模式是否匹配的指示。

        您将从正确缩进代码中受益:

        #!/usr/bin/perl
        use strict;
        use warnings;
        
        my $find = '\s{10}[0-9]{2}\s[A-Z]'; #regex. it can also be '\s{10}[0-9]{2}\s[A-Z]' 
                                            #both dont seem to work
        my @element;
        open (FILE, "foo") || die "can't open file \n";
        while (my $line = <FILE>) {
            chomp ($line);
            print "reached here1 \n"; # to test whether it reading the program properly
            my $value = $line=~ /$find/ ;
            print "reached here 3 \n"; # to test whether it reading the program properly
            print "$value \n";
        }
        exit;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-08
          • 2010-12-06
          • 1970-01-01
          • 2014-05-10
          相关资源
          最近更新 更多