有一个变量定义如下:
my $variable = "This is related to NSQ outage, it is being handled along with all other NSQ alarms. Network team is working on it.";
一些关键字是:CCD_ 1。
当$variable
中有两个或多个关键字时,我可以有一个正则表达式吗?它可以返回true?
示例:
- 当关键字为"is nsq server"时:true
- 当关键字为"nsq-machine-server"时:false
谢谢,我想上面的问题已经解决了
我还有一个问题如下:
my $var="this is related to NSQ outage, and this is";
$var=~/((this|sth).*){2,}/, return true.
实际上$var
中没有"sth",而this
有两个。
在这种情况下,如何使regex返回false?
如果你只需要找到这些关键字中是否至少有两个在字符串中,并且顺序无关紧要,你可以用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;
}
如果在$variable
中找到关键字,则grep
块将返回关键字。如果返回的过滤后的关键字列表至少有两个元素,则匹配为true。
匹配数量量词{}
适用于整词和单个字符。当你想匹配两个或多个你通常会做的事情时:
/x{2,}/
对于完整的单词(比如你的关键词),你可以做:
/((is|nsq|this|server).*){2,}/
示例:
# true:
$variable =~ /((is|nsq|server).*){2,}/;
# false:
$variable =~ /((nsq|machine|server).*){2,}/;
您可以构造一个包含大量|
字符的正则表达式,这些字符可以捕获关键字对的所有可能组合:
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;
您可以为每个想要匹配的关键字添加一个前瞻性,并为要排除的关键字添加负的前瞻性:
^(?!.*bDisallowThisb)(?=.*bMatchThisb)(?=.*bMatchThisb).*$
示例:
将任何字符串与"is"、"nsq"one_answers"server"匹配:
^(?=.*bisb)(?=.*bnsqb)(?=.*bserverb).*$
相同,但不允许关键字"machine":
^(?!.*bmachineb)(?=.*bisb)(?=.*bnsqb)(?=.*bserverb).*$
将字符串与"nsq"、"machine"one_answers"server"匹配:
^(?=.*bnsqb)(?=.*bmachineb)(?=.*bserverb).*$
所以你只需要唯一的匹配-看起来像是一个散列。
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;
};