0

我正在尝试检查文档的每一行是否有正则表达式匹配。如果该行有匹配项,我只想将匹配项推送到一个数组中。

在下面的代码中,我认为g在正则表达式分隔符末尾使用运算符会使s 值$line匹配正则表达式。相反,s 值是包含匹配项的文档的行...$line

my $line;
my @table;
while($line = <$input>){ 

    if($line =~ m/foo/g){

        push (@table, $line);

    }   


}
print @table;

如果有人可以帮助我将匹配项放入数组中,我们将不胜感激。

谢谢。

ps 仍在学习......所以我可能错过的概念的任何解释也非常感谢。

4

3 回答 3

5

g修饰符 ins///g用于全局搜索和替换。

如果您只想将匹配模式推送到数组中,则需要捕获 . 括起来的匹配模式()。捕获的元素存储在变量中$1, $2, etc..

尝试对您的代码进行以下修改:

my @table;
while(my $line = <$input>){ 
    if($line =~ m/(foo)/){
        push (@table, $1);
    }   
}
print @table;

有关更多详细信息,请参阅此文档


或者,如果您想避免不必要地使用全局变量,

my @table;
while(my $line = <$input>){ 
    if(my @captures = $line =~ m/(foo)/){
        push @table, @captures;
    }   
}

这简化为

my @table;
while(my $line = <$input>){ 
    push @table, $line =~ m/(foo)/;
}
于 2013-10-14T18:44:40.110 回答
1

稍微扩展一下 jkshah 的答案,我将匹配项显式存储在 @matches 中,而不是使用我发现有点难以阅读的魔术变量 $1 。 "__DATA__"是一种在 perl 源文件的文件句柄中存储行的简单方法。

use strict;
use warnings;
my @table;
while(my $line = <DATA>){
    my @matches = $line =~ m/(foo)/;
    if(@matches) {
        warn "found: " . join(',', @matches );
        push(@table,@matches);
    }
}
print @table;

__DATA__
herp de derp foo
yerp fool foo flerp
heyhey
于 2013-10-14T18:58:30.843 回答
0

如果您的文件不是很大(100-500mb 适合 2 GB RAM),那么您可以在下面使用。如果匹配的话,我在这里提取数字。这将比 foreach 循环快得多。

#!/usr/bin/perl
open my $file_h,"<abc" or die "ERROR-$!";
my @file = <$file_h>;
my $file_cont = join(' ',@file);
@file =();
my @match = $file_cont =~ /\d+/g;
print "@match";
于 2013-10-14T19:57:46.977 回答