我需要创建一个匹配的正则表达式来找到遗传序列,我被困在一个特定问题后面 - 首先,开始密码子ATG
,跟随三个核苷酸的其他密码子,正则表达式以三个可能的密码子TAA
,TAG
和TGA
结束。如果停止(末端)密码子在开始(ATG
)密码子后出现怎么办?当启动密码子和终止密码子之间存在中间密码子时,我当前的正则表达式起作用,但如果没有,则正则表达式匹配起始密码子后的所有序列。我知道它为什么这样做,但我不知道如何改变它以我想要的方式工作。
我的正则表达式应该寻找AGGAGG
(正是这种模式),然后A
,C
,G
或T
(从4到12次)然后ATG
(恰好这个模式),然后A
,C
,G
或T
(三元组(例如, ACG
,TGC
等等,无论多久都没关系)直到它与TAA
,TAG
或TGA
相匹配。搜索应该在此之后结束并在此之后再次开始。
良好匹配的示例:
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
。贪婪量词将导致第4组捕获第一个TAG
,第二个捕获为结束组。
您可以使用延迟量词:(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], $1, $2, $3, $4, $5, $6 ] })
(?!)
/xg;
Perl必需的正则表达式功能,而不是像grep这样的普通正则表达式,是懒惰的量词:?遵循*或+量词。它匹配零(一)或多个出现在*(+)标记之前的字符作为最短的glob匹配
$seq =~ /((AGGAGG)([ACGT]{4,12})(ATG)([ACGT]{3})*?(TAA|TAG|TGA))/igx