在Perl中成功进行正则表达式匹配后,如何访问捕获的子串?

时间:2009-06-23 17:36:02

标签: regex perl

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

它正在运行的数据

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

以下是我的代码:

#!/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 

4 个答案:

答案 0 :(得分:7)

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

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

请注意,您需要在正则表达式中使用捕获才能使用这些捕获。你尚未做的事。

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

答案 1 :(得分:3)

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
   }
}

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

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是因为你告诉它:这样做的print语句在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;