2015-12-09 38 views
0

我目前正在學習Perl和我試圖找出如何做一個 if string in variable { do stuff }如何使用if語句確定字符串是否在變量中?

我已經嘗試了許多不同的方法,如使用EQ,和=〜但它返回的所有關鍵字keywords.txt內反對該公司在$行

這裏找到特定的關鍵字是我的腳本:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $keywords = 'keywords.txt'; 
open(my $kw, '<:encoding(UTF-8)', $keywords) 
    or die "Could not open file '$keywords' $!" 
    ; # Open the file, throw an exception if the file cannot be opened. 
chomp(my @keywordsarray = <$kw>) 
    ;   # Remove whitespace, and read it into an array 
close($kw); # Close the file 

my $syslog = 'syslog'; 
open(my $sl, '<:encoding(UTF-8)', $syslog) 
    or die "Could not open file '$keywords' $!" 
    ;   # Open the file, throw an exception if the file cannot be opened. 
chomp(my @syslogarray = <$sl>); # Remove whitespace, and read it into an array 
close($sl);      # Close the file 

foreach my $line (@syslogarray) { 
    foreach my $keyword (@keywordsarray) { 
     if ($keyword =~ $line) { 
     print "**" . $keyword . "**" . "\n"; 
     } 
    } 
} 

回答

3

你想

while (my $line = <$sl>) { 
    for my $keyword (@keywordsarray) { 
     if ($line =~ /\b\Q$keyword\E\b/) { 
     print "**$keyword** $line"; 
     } 
    } 
} 

我以前\b,使線abandoned不被認爲包含關鍵字band。請注意,我使用\b時,假設您的關鍵字都以單詞字符開頭和結尾。如果情況並非如此,還需要使用其他東西。

但這是超級慢。您正在編譯number_of_lines * number_of_keywords正則表達式。以下僅編譯一個。這也大大減少了匹配次數。

my $pat = join '|', map quotemeta, @keywordsarray; 
my $re = qr/\b($pat)\b/; 

while (my $line = <$sl>) { 
    while ($line =~ /$re/g) { 
     print "**$1** $line"; 
    } 
} 

如果你只需要知道一個線路是否匹配或沒有,那麼你需要簡單

my $pat = join '|', map quotemeta, @keywordsarray; 
my $re = qr/\b(?:$pat)\b/; 

while (<$sl>) { 
    print if /$re/; 
} 
2

我想你的意思

... 
if ($line =~ m/\Q$keyword\E/) { 
    ... 
} 
... 

這將是a正確檢查以確定變量$keyword內部的文本是否發生在$line的某處;

\Q\E標誌表示在$keyword的文本中不應出現特殊字符。您可以在perldoc perlre

編輯閱讀更多有關Perl的正則表達式標誌:作爲@ikegami指出,不使用\b指示字突破的模式可以產生假陽性。

+0

是的,這確實工作,謝謝。 – Simon

+0

如果你採用這種方法,你應該考慮提前預編譯你的正則表達式,因爲@ikegami建議低於 –

+1

請注意,這將考慮將行「已放棄」以包含關鍵字「band」。這就是爲什麼我使用'\ b' – ikegami

相關問題