0

我正在执行以下代码:

#!/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

我不确定它为什么会这样。有人可以帮助解决上述问题吗?

4

3 回答 3

4

您没有定义匹配的结束,并且p105csi1m1p105csi1m14.

解决方案是在正则表达式中添加 a$以表示行尾。此外,通过使用组,您可以使其更具可读性并为自己节省很多^字符$

my $filter1="^(p1c|...|p105csi1m1)$";
my $filter2="^(p105csi2m13|p105csi1m14)$";
于 2013-02-18T15:39:09.597 回答
1

它是匹配的,因为它以 p105csi1m1 开头;该标准出现在您提供的两个过滤器中。

于 2013-02-18T15:37:14.403 回答
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

请注意,哈希键完全匹配,因此您将没有正则表达式带来的任何灵活性。但在这种情况下,看起来这是一件好事。

于 2013-02-18T15:48:52.713 回答