我目前正在学习Perl,而我正试图弄清楚如何做
if string in variable { do stuff
}
我尝试了很多不同的方法,例如使用eq和=〜但它会返回keywords.txt中的所有关键字,而不是在$ line中找到的特定关键字
这是我的剧本:
#!/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";
}
}
}
答案 0 :(得分: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/;
}
答案 1 :(得分:2)
我认为你的意思是
...
if ( $line =~ m/\Q$keyword\E/ ) {
...
}
...
这将是 a 正确的检查,以确定变量$keyword
内的文本是否出现在$line
的某处;
\Q
和\E
标志表示不应解释$keyword
文本中出现的特殊字符。您可以在perldoc perlre
编辑:正如@ikegami指出的那样,不使用\b
表示单词分词,上面的模式可能会给出误报。