我正在使用regex
,但我得到一些奇怪的,意外的"匹配"。 "名称"被发送到子程序以与名为@ASlist
的数组进行比较,该数组包含多行。每行的第一个元素也是一个名称,后跟0到几个同义词。目标是匹配传入的"名称"到@ASlist
中具有匹配单元格的任何行。
示例输入,从中导出$names
以与@ASlist
进行比较:
13 1 13 chr7 7 70606019 74345818 Otud7a Klf13 E030018B13Rik Trpm1 Mir211 Mtmr10 Fan1 Mphosph10 Mcee Apba2 Fam189a1 Ndnl2 Tjp1 Tarsl2 Tm2d3 1810008I18Rik Pcsk6 Snrpa1 H47 Chsy1 Lrrk1 Aldh1a3 Asb7 Lins Lass3 Adamts17
来自@ASlist的样本行:
HSPA5 BIP FLJ26106 GRP78 MIF2
NDUFA5 B13 CI-13KD-B DKFZp781K1356 FLJ12147 NUFM UQOR13
ACAN AGC1 AGCAN CSPG1 CSPGCP MSK16 SEDK
代码:
my ($name) = @_; ## this comes in from another loop elsewhere in code I did not include
chomp $name;
my @collectmatches = (); ## container to collect matches
foreach my $ASline ( @ASlist ){
my @synonyms = split("\t", $ASline );
for ( my $i = 0; $i < scalar @synonyms; $i++ ){
chomp $synonyms[ $i ];
#print "COMPARE $name TO $synonyms[ $i ]\n";
if ( $name =~m/$synonyms[$i]/ ){
print "\tname $name from block matches\n\t$synonyms[0]\n\tvia $synonyms[$i] from AS list\n";
push ( @collectmatches, $synonyms[0], $synonyms[$i] );
}
else {
# print "$name does not match $synonyms[$i]\n";
}
}
}
该脚本正在运行,但也会报告奇怪的匹配。例如,当$name
是&#34; E030018B13Rik&#34;它匹配&#34; NDUFA5&#34;当它发生在@ASlist
时。这两个不应该匹配。
如果我将正则表达式从~m/$synonyms[$i]/
更改为~m/^$synonyms[$i]$/
,那么&#34;怪异的&#34;比赛消失,但剧本错过绝大多数比赛。
答案 0 :(得分:1)
NDUFA5
条记录包含B13
作为模式,与E030018<B13>Rik
匹配。
如果您想更加文字,请将边界条件添加到正则表达式/\b...\b/
。也应该使用quotemeta
来转义正则表达式特殊字符。
if ( $name =~ m/\b\Q$synonyms[$i]\E\b/ ) {
或者,如果您想测试直接相等,那么只需使用eq
if ( $name eq $synonyms[$i] ) {
答案 1 :(得分:1)
测试字符串相等性的另一种更多Perlish方法是使用散列。
您没有显示任何真实的测试数据,但是这个简短的Perl程序会根据匹配字符串行的数组@ASlist
构建一个哈希值。之后,大部分工作都已完成。
后续的for
循环仅测试E030018B13Rik
以查看它是否是新%ASlist
的键之一并打印相应的消息
use strict;
use warnings;
my @ASlist = (
'HSPA5 BIP FLJ26106 GRP78 MIF2',
'NDUFA5 B13 CI-13KD-B DKFZp781K1356 FLJ12147 NUFM UQOR13',
'ACAN AGC1 AGCAN CSPG1 CSPGCP MSK16 SEDK',
);
my %ASlist = map { $_ => 1 } map /\S+/g, @ASlist;
for (qw/ E030018B13Rik /) {
printf "%s %s\n", $_, $ASlist{$_} ? 'matches' : 'doesn\'t match';
}
<强>输出强>
E030018B13Rik doesn't match
答案 2 :(得分:0)
您使用B13
作为正则表达式。由于没有任何字符具有特殊含义,因此包含子字符串B13
的任何字符串都与表达式匹配。
E030018B13Rik
^^^
如果希望表达式与整个字符串匹配,请使用锚点:
if ($name =~m/^$synonyms[$i]$/) {
或者,使用index
或eq
来检测子串(或分别为相同的字符串),因为您的输入似乎不使用正则表达式的任何功能。
答案 3 :(得分:0)
由于您只需要比较两个字符串,您只需使用eq:
即可if ( $name eq $synonyms[$i] ){