有一个使用正则表达式的程序,不知怎的,我无法理解它。
代码+ - 像这样:
@listOfIds = &methodToGetIDs();
foreach my $id (@listOfIds){
if($class =~ /gen/ig){
#does stuff
}
}
我理解的是,如果$class
有"gen"
,那么它会进入if{}
,但有时它会不会进入它,所以我放了一个其他的看到发生了什么,代码最终像这样:
my $class = "genes";
foreach my $id (@listOfIds){
if($class =~ /gen/ig){
print $class."\n"; #to see the value of class
}else{
print "!!!".$class."\n"; #to see the difference if there's any
}#miss this wooops!
}
猜猜是什么?输出是这样的:
genes
genes
!!!genes
genes
genes
!!!genes
genes
genes
!!!genes
如果$class
的值没有改变那么为什么它会进入else子句?猜猜我根本不理解正则表达式。有线索吗?
答案 0 :(得分:2)
因为您使用的是/g
选项。来自perlop:
在标量上下文中,
m//g
的每次执行都会找到下一个匹配项,如果匹配则返回true,如果没有进一步匹配则返回false。可以使用pos()
函数读取或设置最后一次匹配后的位置;见pos。失败的匹配通常会将搜索位置重置为字符串的开头,...
所以,你第一次看到这个字符串时会得到一个匹配。然后,下次你在第一场比赛的位置后开始。即该位置不会重置为字符串的开头,而是在第一次匹配发生的位置继续。
/g
标志用于表示您希望在字符串中匹配 all 的次数。这对于计算字符串中出现子串的次数很有用。在您的情况下,您正在测试模式是否匹配,是否真实,如果匹配,则执行某些操作。在这种情况下,您不需要/g
标志。
my $class = "genes";
foreach my $id (1..6){
if($class =~ /gen/ig){
print $class."\n"; #to see the value of class
}else{
print "!!!".$class."\n"; #to see the difference if there's any
}
}
输出:
genes
!!!genes
genes
!!!genes
genes
!!!genes
如果您删除/g
标记,则会获得:
genes
genes
genes
genes
genes
genes
答案 1 :(得分:0)
perlop联机帮助页显示:
在标量上下文中,m // g的每次执行都会找到下一个匹配项, 如果匹配则返回true,如果没有进一步匹配则返回false。
由于if
评估表达式中标量上下文中的条件,因此每次它首先返回true,然后返回false,因为没有进一步的匹配(我不明白为什么它打印两次,并且你的代码无法编译。)
但请注意:
if ( $class =~ /gen/i ) {
总是在您的示例中为真,因为$class = "genes"
并且似乎没有变化。您的意思是检查$id
吗?
无论如何,/g
修饰符似乎不适合您的代码。