您重新聲明my $line
在你的內循環,這意味着它將等於:
if (undef =~ /$array[$x]/) {
這當然總是會失敗。如果您用過use warnings
,你會得到錯誤:
Use of uninitialized value in pattern match (m//) at ...
這讓我沒有使用警告懷疑,這是一個非常壞主意。
另外,請記住,當您將值讀入@array
時,您將在最後得到一個換行符,因此您在DAT文件中搜索以\n
結尾的字符串,這可能不是您想要的。例如。如果您有foo\n
,則它不會匹配foo bar baz
。
該解決方案是chomp
您的數據:
chomp(my @array = <TXT>);
是的,你可以的Chomp的數組,你可以指定整個文件到一個數組這種方式。
你可以也應該改進你的腳本。除非實際上需要使用索引來進行某些操作,否則使用數組索引進行循環是非常不必要的。
use strict;
use warnings; # ALWAYS use these!
use autodie; # handles the open statements for convenience
my $source = "/KEYS.txt";
my $data= "/claims.dat";
open $txt, '<', $source;
chomp(my @array = <$txt>);
close $txt;
open my $dat, '<', $data; # use three argument open and lexical file handle
open my $log, '>>', "/output.log";
while (<$dat>) { # using $_ for convenience
for my $word (@array) {
if (/\Q$word/i) { # adding /i modifier to match case insensitively
print $log $line; # also adding \Q to match literal strings
}
}
使用\Q
可能是非常重要的,這取決於你的KEYS.txt文件包含。正則表達式的元字符可能會導致細微的不匹配,如果您期望它們字面匹配。例如。如果你有一個詞,如foo?
,正則表達式/foo?/
將匹配foo
,但它也將匹配for
。
此外,您可能希望決定是否允許部分匹配。例如。 /foo/
也將匹配football
。爲了克服這種情況,一種方法是使用單詞邊界轉義字符:
/\b\Q$word\E\b/i
你需要將它們放在\Q .. \E
序列之外,否則將被字面解釋。正如tchrist指出的那樣,Borodin建議,用所有單詞構建一個正則表達式可以節省您重複的行數。例如。如果您的文字爲"foo"
,"bar"
和"baz"
,並且行foo bar baz
您會得到這行打印三次,每個匹配的單詞一次。
之後可以通過以某種合適的方式扣除數據來解決此問題。只有你知道你的數據以及這是否是一個問題。由於性能原因,我會毫不猶豫地編譯這麼長的正則表達式,但您可以嘗試一下,看看它是否適合您。
來源
2012-03-22 18:48:59
TLP
對於這個特定的問題,您可以可能使用'grep'(在Linux/Unix版本,不使用Perl)。例如。 'grep -f /KEYS.txt/claims.dat'。 – TLP 2012-03-22 19:02:39
KEYS.txt中的字符串是固定的還是他們的正則表達式?如果它們是固定的,用'grep -F -f KEYS.txt claims.dat'獲得巨大的速度勝利; Perl代碼將使用['index'](http://p3rl.org/index)函數而不是匹配運算符。 – daxim 2012-03-22 19:12:36
在KEYS.txt中,它們實際上是9位數字。所以102361550和481543095等 – cluckinchicken 2012-03-22 19:45:40