将正则表达式匹配仅放入数组,而不是整行

时间:2013-10-14 18:38:24

标签: regex arrays perl

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

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

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

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

        push (@table, $line);

    }   


}
print @table;

如果任何人可以帮助我将我的比赛变成阵列,我们非常感激。

感谢。

P.S。 还在学习......所以我可能错过的任何概念解释也非常感激。

3 个答案:

答案 0 :(得分:5)

g中的

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

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

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

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

有关详细信息,请参阅此documentation


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

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)/;
}

答案 1 :(得分: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

答案 2 :(得分:0)

如果你的文件不是很大(2 GB内存100-500mb),那么你可以使用下面的内容。如果我在线匹配,我将提取数字。它将比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";