我正在执行以下代码:
#!/usr/bin/perl -w
my $filter1="^p1c|^p2c|^p3c|^p11c|^p23c|^p105csi1m1|^p105csi1m2|^p105csi1m13|^p105csi2m14|^p101csi1m1|^p101csi1m2|^p101csi1m13|^p101csi2m14|^p103csi1m1|^p103csi1m2|^p103csi1m13|^p103csi2m16|^p102csi1m1|^p102csi1m2|^p102csi1m13|^p102csi2m16|^p100csi1m4|^p100csi1m5|^p100csi2m13|^p100csi1m14";
my $filter2="^p105csi2m13|^p105csi1m14";
$n1="p105csi1m14";
my $m1 .= "$n1 " if($n1 =~ m/$filter1/);
my $m2 .= "$n1 " if($n1 =~ m/$filter2/);
print "\nmatch 1 => $m1\n";
print "\nmatch 2 => $m2\n";
以上代码的输出如下:
match 1 => p105csi1m14
match 2 => p105csi1m14
预期结果如下:
match 1 =>
match 2 => p105csi1m14
我不确定为什么这样做。有人可以帮忙解决上述问题吗?
答案 0 :(得分:4)
您没有定义匹配的结尾,p105csi1m1
是p105csi1m14
的子字符串。
解决方法是在正则表达式中添加$
以表示该行的结尾。此外,通过使用群组,您可以使其更具可读性,并为自己节省大量^
和$
个字符。
my $filter1="^(p1c|...|p105csi1m1)$";
my $filter2="^(p105csi2m13|p105csi1m14)$";
答案 1 :(得分:1)
匹配是因为它以p105csi1m1开头;该标准会出现在您提供的两个过滤器中。
答案 2 :(得分:1)
一方面,你为自己制造困难。你的正则表达式匹配得比它应该多,因为它只锚定在字符串的开头。你需要在最后锚定它以避免部分匹配。此外,您还有许多可以简化的重复文本:
my @words = qw(p1c p2c p3c p11c p23c p105csi1m1 p105csi1m2 p105csi1m13
p105csi2m14 p101csi1m1 p101csi1m2 p101csi1m13 p101csi2m14
p103csi1m1 p103csi1m2 p103csi1m13 p103csi2m16 p102csi1m1
p102csi1m2 p102csi1m13 p102csi2m16 p100csi1m4 p100csi1m5
p100csi2m13 p100csi1m14);
my $filter1 = '^(?:' . join('|', @words) . ')$';
虽然使用哈希查找可能更好地解决了这个问题:
my %lookup = map { $_ => 1 } @words; # create a key for each word
my $m1 .= "$n1 " if($lookup{$n1}); # check if key exists
请注意,哈希键完全匹配,因此您将无法获得正则表达式带来的任何灵活性。但在这种情况下,看起来这是件好事。