你能解释一下为什么\我的Perl正则表达式模式中的G表现如此吗?

use*_*944 5 regex perl

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

答案是:

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";
}
Run Code Online (Sandbox Code Playgroud)

这打印:

Got a TGA stop codon at position 18

怎么样?

Ibr*_*jar 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说.


Tom*_*lak 1

*?你根本不需要使用。

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

印刷

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

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

  • 非捕获组 (?: ...) 并不是真正必要的。您可以使用普通组。
  • 另一种变体是/[TGAC]{3}TGA/g.