$dna = "ATCGTTGAATGCAAATGACATGAC";
while ($dna =~ /(\w\w\w)*?TGA/g) { # note the minimal *?
print "Got a TGA stop codon at position ", pos $dna, "\n";
}
答案是:
Got a TGA stop codon at position 18 Got a TGA stop codon at position 23
为什么位置18,但不是8?以下23.我很困惑它是如何匹配的?关于比赛的详细信息是什么?
但正确的代码是:
while ($dna =~ /\G(\w\w\w)*?TGA/g) {
print "Got a TGA stop codon at position ", pos $dna, "\n";
}
打印:
Got a TGA stop codon at position 18
如何?
答案 0 :(得分:6)
正如@Tomalak所说,你不需要*?
,因为这是你情况混乱的原因。以下是您的第一段代码中的内容:
它看到(\w\w\w)*?
不情愿(可选)所以它跳过它并尝试匹配TGA
但没有运气因此引擎回溯并匹配三个连续的单词字符阅读ATC
,现在再次尝试匹配TGA
但又没有运气,因此它连续三次读取\w
并且引擎到目前为止已读取ATCGTT
。
现在它再次尝试TGA
并且没有运气,然后再次回溯并再次阅读\w\w\w
,现在它已经ATCGTTGAA
,现在尝试查找TGA
但它已经在读取最后三个\w
时跳过第一个,因此这就是引擎无法找到第一个TGA
因此无法报告其位置的原因。
现在引擎继续这件事,直到它找到TGA
之后的AAA
(如果你像我一样继续前进,你会看到这是怎么回事) ,现在它执行循环打印18内的指令。
由于您已使用/g
修饰符,下一次匹配尝试将从第一个匹配尝试开始并失败,然后在最后一个匹配后尝试另一个匹配跳过单个字符,依此类推,直到匹配最后TGA
并打印23。
那么为什么在第二种情况下它只匹配18处的一个位置,使用\G
修饰符的效果是什么?
一切都一样,直到找到第一个匹配,就像前三个AAA
之后的情况一样,然后当下一个匹配开始时,它尝试匹配\G
,这意味着尝试匹配最后一个匹配在AAATGA
之后结束并且它起作用,然后它尝试匹配字符串的其余部分但是失败,但是这次当引擎试图跳过一个或两个或三个左右时,它总是会尝试首先匹配\G
,除非匹配是在上一个结束时开始的(即AAATGA
之后)所以它会一直失败,因此只报告一个18岁的单场比赛。
只需删除*?
@Tomalak说。
答案 1 :(得分:1)
您根本不需要使用*?
。
$dna = "ATCGTTGAATGCAAATGACATGAC";
while ($dna =~ /(?:\w\w\w)TGA/g) {
print "Got a TGA stop codon at position ", pos $dna, "\n";3.
}
打印
Got a TGA stop codon at position 8 Got a TGA stop codon at position 18
请注意*?
使前面的原子可选,但实际上你希望它是必需的。
/[TGAC]{3}TGA/g
。答案 2 :(得分:0)
在第18位获得TGA终止密码子
第一场比赛是在第18位而非第8场的原因是因为第18位的比赛是最左侧比赛:
(ATC) (GTT) (GAA) (TGC) (AAA) [TGA] CATGAC
0 3 6 9 12 15 18
此匹配发生在零开始位置,在TGA之前可以匹配(\ w \ w \ w)5次。
但是导致pos 8的匹配发生在2的起始位置,它可以在TGA之前匹配(\ w \ w \ w)一次:
AT (CGT) [TGA] ATGCAAATGACATGAC
2 5 8
正则表达式更喜欢最左侧匹配。
添加\G
需要在开始时(或在您的上一场比赛之后)锚定匹配。在这种情况下,只有当TGA是字符串开头的3个字符的倍数时才会匹配TGA。这是你需要的吗?