如何使用if语句确定字符串是否在变量中?

时间:2015-12-09 20:06:54

标签: perl if-statement

我目前正在学习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";
      }
   }
}

2 个答案:

答案 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

中阅读有关Perl正则表达式标志的更多信息

编辑:正如@ikegami指出的那样,不使用\b表示单词分词,上面的模式可能会给出误报。