2013-10-14 12 views
0

我想檢查文檔的每一行以進行正則表達式匹配。 如果線路匹配,我想將匹配只有推到一個數組中。把正則表達式匹配到數組中,而不是整行

在下面的代碼,我認爲使用g操作者在正則表達式的分隔符的結束將使$line價值的正則表達式匹配。相反$line價值是整個線包含匹配的文件...

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

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

     push (@table, $line); 

    } 


} 
print @table; 

如果任何人能幫助我讓我的比賽到一個數組,這是大加讚賞。

謝謝。

p.s. 不斷學習...所以我可能錯過的概念的任何解釋也非常感謝。

+0

知道*爲什麼*你認爲'g'修飾符會這樣做 - 是否有一些文檔可以改進? – hobbs

回答

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

添加了一些更簡單的變化。 – ikegami

+0

@ikegami感謝您的編輯。 – jkshah

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 
0

如果文件不是很大(100-500mb罰款2 GB RAM),那麼你可以使用below.Here我提取號碼,如果在line.It匹配會比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";