1

有一个变量定义如下:

my $variable = "This is related to NSQ outage, it is being handled along with all other NSQ alarms. Network team is working on it.";

一些关键字是:"is nsq this server".

当有两个或多个关键字时,我可以有一个正则表达式$variable,它可以返回 true 吗?

例子:

  • 当关键字是“是 nsq 服务器”时:true
  • 当关键字为“nsq machine server”时:false

谢谢,我想上面的问题已经解决了。

我还有一个问题如下:

my $var="this is related to NSQ outage, and this is"; 

$var=~/((this|sth).*){2,}/, return true. 

实际上没有'sth' $var,并且this有两个。

在这种情况下如何使正则表达式返回 false?

4

5 回答 5

2

如果您只需要查找这些关键字中是否至少有两个在字符串中并且顺序无关紧要,您可以这样做grep

my $variable = "This is related to NSQ outage, it is being handled along with all other NSQ alarms. Network team is working on it.";
my @keywords = qw(is nsq server);

if ( ( grep { $variable =~ m/\b$_\b/i } @keywords ) >= 2) {
  print $variable;
}

如果在 中找到该grep块,它将返回一个关键字$variable。如果返回的过滤后的关键字列表至少包含两个元素,则您的匹配为真。

于 2013-08-19T07:14:18.893 回答
1

您可以构造一个包含许多|字符的正则表达式,这些字符可以捕获关键字对的所有可能组合:

foreach my $k1 (@keywords) {
foreach my $k2 (@keywords) {
    next if $k1 eq $k2;
    push @expr, "\\b$k1\\b.*\\b$k2\\b";
}
}
$the_regex = join '|', @expr;

...
$variable =~ /$the_regex/i;
于 2013-08-19T06:55:21.477 回答
1

匹配数量量词{}适用于整个单词以及单个字符。当你想匹配两个或更多你通常会做的事情时:

/x{2,}/

对于整个单词(例如您的关键字),您可以执行以下操作:

/((is|nsq|this|server).*){2,}/

例子:

# true:
$variable =~ /((is|nsq|server).*){2,}/; 

# false:
$variable =~ /((nsq|machine|server).*){2,}/; 
于 2013-08-19T07:14:52.873 回答
0

您可以为要匹配的每个关键字添加一个预测,为要排除的关键字添加一个否定预测:

^(?!.*\bDisallowThis\b)(?=.*\bMatchThis\b)(?=.*\bMatchThis\b).*$


示例:

匹配任何字符串与“is”、“nsq”和“server”:

^(?=.*\bis\b)(?=.*\bnsq\b)(?=.*\bserver\b).*$

相同,但不允许使用关键字“machine”:

^(?!.*\bmachine\b)(?=.*\bis\b)(?=.*\bnsq\b)(?=.*\bserver\b).*$

用“nsq”、“machine”和“server”匹配字符串:

^(?=.*\bnsq\b)(?=.*\bmachine\b)(?=.*\bserver\b).*$
于 2013-08-19T07:47:12.387 回答
0

所以你只需要唯一的匹配 - 看起来像一个哈希的工作。

use strict;
use warnings;

my $right = "This is related to NSQ server outage";
my $wrong = "server is a server server";
my $regex = qr(server|nsq)i;

print "right" if uniq_matches( $right, $regex ) > 1;
print "wrong" if uniq_matches( $wrong, $regex ) > 1; 

sub uniq_matches {
     my ($str, $regex) = @_;
     my %match;
     $match{$1}++ while $str =~ m/($regex)/g;
     return keys %match;
};
于 2013-08-19T14:52:57.027 回答