仅当不匹配其他模式时才匹配特定模式的正则表达式

Regex for matching a specific pattern only if it doesn't match other pattern

我需要创建一个匹配的正则表达式来查找基因序列,但我遇到了一个具体问题 - 首先是起始密码子 ATG,然后是来自三个核苷酸的其他密码子,正则表达式以三个结尾可能的密码子 TAATAGTGA。如果终止(结束)密码子在起始(ATG)密码子之后怎么办?我当前的正则表达式在起始密码子和终止密码子之间存在中间密码子时有效,但如果有 none,则正则表达式匹配起始密码子之后的所有序列。我知道它为什么这样做,但我不知道如何更改它以按照我想要的方式工作。

我的正则表达式应该寻找 AGGAGG(正是这个模式),然后是 ACGT(从 4 到 12次)然后是 ATG(正是这种模式),然后是 ACGT(三元组(例如,ACG , TGC 等),不管多长时间)直到它匹配 TAATAGTGA。搜索应该在那之后结束,然后再次开始。

良好匹配示例:

XXXXXXXXXXXXXXXXXXXXXXXXX   XXXXXXXXXXXXXXXX
AGGAGGTATGATGCGTACGGGCTAGTAGAGGAGGTATGATGTAGTAGCATGCT

序列中有两个匹配项 - 从 0 到 25 和从 28 到 44。

我当前的正则表达式(不要介意前两个括号):

$seq =~ /(AGGAGG)([ACGT]{4,12})(ATG)([ACTG]{3,3}){0,}(TAA|TAG|TGA)/ig

这里的问题来自贪婪量词的默认用法。

当使用(AGGAGG)([ACGT]{4,12})(ATG)([ACTG]{3})*(TAA|TAG|TGA)时,第4组([ACTG]{3})*将尽可能匹配,然后只考虑第5组(如果需要回溯)。
在你的序列中你得到 TAGTAG。贪心量词将导致第一个 TAG 被捕获在第 4 组中,第二个被捕获为结束组。

您可以改用惰性量词:(AGGAGG)([ACGT]{4,12})(ATG)([ACTG]{3})*?(TAA|TAG|TGA)(注意添加的问号,使量词变得惰性)。
这样,遇到的第一个 TAG 将被视为结束组。

Demo.

根据您提供的模式,您可能会出现重叠匹配。以下将找到所有匹配项,包括重叠匹配项:

local our @matches;
$seq =~ /
   (
   ( AGGAGG )
   ( [ACGT]{4,12} )
   ( ATG )
   ( (?: (?! TAA|TAG|TGA ) [ACTG]{3} )* )
   ( TAA|TAG|TGA )
   )
   (?{ push @matches, [ $-[1], , , , , ,  ] })
   (?!)
/xg;

Perl 基本的正则表达式功能,与像 grep 这样的普通正则表达式相反,是惰性量词:?在 * 或 + 量词之后。它匹配零(一次)或多次出现的*(+)标记之前的字符作为最短的 glob 匹配尽可能

$seq =~ /((AGGAGG)([ACGT]{4,12})(ATG)([ACGT]{3})*?(TAA|TAG|TGA))/igx