5
$dna = "ATCGTTGAATGCAAATGACATGAC";
while ($dna =~ /(\w\w\w)*?TGA/g) {  # note the minimal *?        
    print "Got a TGA stop codon at position ", pos $dna, "\n";
}

答案是:

在第 18 位有一个 TGA 终止密码子    
在第 23 位有一个 TGA 终止密码子

为什么位置是 18 而不是 8?以及下面的 23. 我很困惑它是如何匹配的?比赛的详细信息是什么?

但正确的代码是:

while ($dna =~ /\G(\w\w\w)*?TGA/g) {        
  print "Got a TGA stop codon at position ", pos $dna, "\n";
}

这打印:

在第 18 位有一个 TGA 终止密码子

如何?

4

3 回答 3

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 所说,只需删除即可。

于 2013-08-19T10:36:03.673 回答
1

你根本不需要使用*?

$dna = "ATCGTTGAATGCAAATGACATGAC";
while ($dna =~ /(?:\w\w\w)TGA/g) {
    print "Got a TGA stop codon at position ", pos $dna, "\n";3.    
}

印刷

在第 8 位有一个 TGA 终止密码子
在第 18 位有一个 TGA 终止密码子

请注意,这*?使前面的原子成为可选的,但您实际上希望它是必需的。

  • 非捕获组 (?: ...) 并不是必需的。您可以使用普通组。
  • 另一个变体是/[TGAC]{3}TGA/g.
于 2013-08-19T09:43:27.923 回答
0

在第 18 位有一个 TGA 终止密码子

第一个匹配在 pos 18 而不是 8 的原因是因为 pos 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。这是你需要的吗?

于 2013-08-19T10:31:47.267 回答