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

あなたはマッチの終わりを定義しておらずp105csi1m1、 の部分文字列ですp105csi1m14

解決策は、正規表現に a を追加し$て、行の終わりを示すことです。また、グループを使用すると、読みやすくなり、多くの文字を節約でき^ます$

my $filter1="^(p1c|...|p105csi1m1)$";
my $filter2="^(p105csi2m13|p105csi1m14)$";
于 2013-02-18T15:39:09.597 に答える
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 に答える
1

p105csi1m1 で始まるので一致しています。その条件は、指定した両方のフィルターに表示されます。

于 2013-02-18T15:37:14.403 に答える