在每行文件中打印匹配的第一个实例(Perl)

时间:2013-05-31 23:49:05

标签: regex perl

我在可执行文件.pl文件中有以下内容:

#!/usr/bin/env perl
$file = 'TfbG_peaks.txt';
open(INFO, $file) or die("Could not open file.");

foreach $line (<INFO>) {
        if ($line =~ m/[^_]*(?=_)/){
                #print $line; #this prints lines, which means there are matches
                print $1; #but this prints nothing
        }
}

根据我在http://goo.gl/YlEN7http://goo.gl/VlwKe的阅读情况,print $1;应该在每一行中打印第一个匹配,但事实并非如此。救命啊!

2 个答案:

答案 0 :(得分:2)

不,$1应该打印由所谓的capture groups保存的字符串(由包围构造创建 - ( ... ))。例如:

if ($line =~ m/([^_]*)(?=_)/){
   print $1; 
   # now this will print something, 
   # unless string begins from an underscore 
   # (which still matches the pattern, as * is read as 'zero or more instances')
   # are you sure you don't need `+` here?
}

原始代码中的模式没有任何捕获组,这就是为什么$1为空(undef为准确)。并且(?=...)没有计算,因为这些用于添加前瞻性子表达式。

答案 1 :(得分:0)

$1打印捕获的模式中的第一个捕获((...))。

也许你在考虑

print $& if $line =~ /[^_]*(?=_)/;    # BAD

print ${^MATCH} if $line =~ /[^_]*(?=_)/p;   # 5.10+

但以下会更简单(并且在5.10之前工作):

print $1 if $line =~ /([^_]*)_/;

注意:如果添加了引导^(?:^|_)(以适当者为准),模式不匹配时,您将获得性能提升。

print $1 if $line =~ /^([^_]*)_/;