2015-09-23 104 views
2

我試圖從文本文件中使用常規擴展提取某些數字字符串,但是當我的代碼運行時,它在日期和時間之間的分隔之後抓取數字。這是我到目前爲止。Perl正則表達式提取

while (<INFILE>) { 

    my @fields = split(/\ /, $_); 
    my @output; 

    foreach my $field (@fields) { 
     if ($field =~ /[0-9]{5}\//) { 
      push @output, $field; 
     } 
    } 

    if (@output) { 
     my $line = join(' ', @output); 
     print "$line\n"; 
     print OUTFILE "$line\n"; 
    } 
} 

行我試圖提取數據從是

D20/2004 254/1944 254/2041 15254/2011 ALL-V4YM 001 AUTO C-C0000 

我需要的數據是15254但是當我運行我的代碼返回15254/2011和我的程序示數出來。

回答

4

問題是,您將整個$field存儲在輸出數組中,但您只希望存儲斜槓左側的數字。您可以在正則表達式和特殊變量中使用捕獲圓括號。該輸出15254

use warnings; 
use strict; 

while (<DATA>) { 
    my @fields = split(/\ /, $_); 
    my @output; 
    foreach my $field (@fields) { 
     if ($field =~ /^([0-9]{5})\//) { 
      push @output, $1; 
     } 
    } 
    if (@output) { 
     my $line = join(' ', @output); 
     print "$line\n"; 
    } 
} 

__DATA__ 
D20/2004 254/1944 254/2041 15254/2011 ALL-V4YM 001 AUTO C-C0000 
+1

我建議增加林的開始e錨定到您的表情,所以如果其中有五個以上的數字,則不會捕獲該字段。 '/ ^([0-9] {5})\ //' –

+0

@TrentonTrama:好主意。更新。 – toolic

+0

如果你不喜歡'$ 1',你也可以使用'my($ value)= $ field =〜m,^(\ d {5})\/;;'。 – Sobrique

1

由於斜線

split如前所述,要保存整個領域@output,如果它的正則表達式匹配,而不是僅僅是第一部分,也是不必要的複雜,以及join不需要

所有你需要的是這樣的

while (<INFILE>) { 

    my @output = map m{^([0-9]{5})/}, split; 

    if (@output) { 
     print "@output\n"; 
     print OUTFILE "@output\n"; 
    } 
}