2009-08-02 42 views
0

我正在將正則表達式捕獲的信息存儲到數組中。但由於某種原因,第一個值被存儲在數組的4個元素中。任何關於什麼是錯誤的建議以及如何將第一個值存儲在數組的第一個元素中。爲什麼捕獲的表達式的第一個值被存儲在Perl的第四個元素中?

下面是腳本:

#!/usr/bin/perl 

use strict; 
my @value; 
my $find= qr/^\s+([0-9]+)\s+([A-Z])/; 

open (FILE, "</usr/test")|| die "cant open file"; 
my @body=<FILE>; 

foreach my $line (@body){ 
    chomp $line; 
    push @value, join('', $line =~ /$find/); 
} 
print "$value[0]\n"; #does not print anything 
print "$value[4]\n"; #prints first value i.e 1389E 
exit; 

DATA

1389 E not 
    188 S yes 
    24 D yes 
    456 K not 
    2 Q yes 

回答

1

我想你應該寫

print "$value[0]\n"; 
print "$value[4]\n"; 

訪問數組元素。

+0

@大衛:我誤[0]寫到@value。我使用$ value [0]打印數組的第一個值。並且,第一個元素沒有值打印,例如$ value [0] – shubster 2009-08-02 01:29:13

4

您的第二行在數字組和字母之間有多個空格,所以您可能需要第二次輸入\s+而不是第二次輸入\s

您不一定知道最後@value陣列中有多少物品,因此您可能希望將打印放入for循環中,而不是假設您有第五個物品。 (也許你知道你想要第一個和第五個,但是?)後續:根據你的編輯,你畢竟有兩個以上的條目。我在下面給出的版本,使用split\s+捕獲所有行的數字和字母。我會調整腳本的打印部分以向您展示我的意思。

一些其他的東西:

  • 你應該總是啓用警告。
  • 沒有理由將整個文件讀入數組,然後逐行處理。跳過@body陣列,只需在while循環中執行所需操作即可。
  • 使用帶有詞法文件句柄和三個參數的更現代的open形式。
  • split在這裏對我來說似乎更直截了當,而不是一個帶捕獲的正則表達式。由於您想要捕獲該行的兩個特定部分,因此可以使用split和一個數組切片來抓取這兩個項目並將它們提供給join
  • @value不是一個特別有用的變量名稱,但我認爲你應該至少使其複數。我認爲,就數組存儲您的複數記錄而言,這是一個很好的習慣。 (。這不是一個硬性的規定,但在這裏竊聽我這點是非常小的)

下面是這一切看起來:

#!/usr/bin/env perl 
    use warnings; 
    use strict; 

    my @values; 

    # open my $filehandle, '<', '/usr/test' 
    #  or die "Can't open /usr/test: $!"; 

    while (my $line = <DATA>) { 
     chomp $line; 
     push @values, join('', (split /\s+/, $line)[1..2]); 
    } 

    for my $record (@values) { 
     print $record, "\n"; 
    } 

    __DATA__ 
     1389 E not 
     188 S yes 
     24 D yes 
     456 K not 
     2 Q yes 
+0

不應該在您的代碼示例中使用「...使用詞法文件句柄和三個參數打開窗體」嗎?還有一個範圍要走出去?或者我誤解了一些東西? – 2009-08-03 00:36:06

+0

@Peter:我實際上不能使用`open`語句,因爲我的驅動器上沒有OP的/ usr/test文件(我不打算爲這個例子創建它)。所以我寫了這個例子來向他展示我的意思,但我使用內置的__DATA__來獲取文件。至於「走出去的範圍」,在這個短小的劇本中,問題本身並不是真正的範圍。我沒有強調詞彙文件句柄中的「詞法」;這只是他們的名字。看到這裏更多關於裸字文件句柄:http://www.perlfoundation.org/perl5/index.cgi?bareword_uppercase_filehandles – Telemachus 2009-08-03 01:48:05

1

您應該使用詞法文件句柄和三種參數形式的open,以及避免不必要的sl files文件。

在任何情況下,最可能的原因是您的模式中缺少單個字符。將下面的一個與上面的一個進行比較。

#!/usr/bin/perl 

use strict; 
use warnings; 

my @value; 
my $find= qr/^\s+([0-9]+)\s+([A-Z])/; 

while (my $line = <DATA>) { 
    last unless $line =~ /\S/; 
    push @value, join '', $line =~ $find; 
} 

use Data::Dumper; 
print Dumper \@value; 

__DATA__ 
    1389 E not 
    188 S yes 
    24 D yes 
    456 K not 
    2 Q yes 
0

您的數據中的主要空白行或其他引導行與您的正則表達式不匹配嗎?由於您無條件地將())push()到輸出數組上,無論您的正則表達式是否匹配,您的輸入中的每個不匹配行都會得到空白數組元素。

觀察:

#!/usr/bin/perl 

use strict; 
use warnings; 

my @lines; 

while (<DATA>) { 
    push @lines , (join('' , /^\s*(\d+)/)); 
} 

foreach (0 .. $#lines) { 
    print "$_ -> $lines[$_]\n"; 
} 


__DATA__ 
FOO 
Bar 
Baz 
    1234 
456 
bargle 

輸出:

0 -> 
1 -> 
2 -> 
3 -> 1234 
4 -> 456 
5 -> 
相關問題