perl regex:如何在没有内部停止密码的情况下获得开放阅读框架?

时间:2013-07-08 14:09:17

标签: regex perl substring bioinformatics

我试图以串的形式从(DNA)基因组序列的一条链中分离出所有重叠的ORFs(包括基因组上的起始(i)和终止(j)位置以及ORF的长度(1)); ORF应以ATG开始,具有至少24个内部核苷酸[ACGT]并以(TAA | TAG | TGA)结束。

通过查看find ORF with minimal size of 45 bases using perl regular expression - why this regex doesn't work我想出了这个(所以需要进行调整):

    my $genome = $_[0];
    my $ATG_count = 0;
    my $ORF_count = 0;
    my @i = (); 
    my @j = (); 
    my @l = (); 
    my @frames = (); 

    while ($genome =~ m/ATG/ig) {   ### I need to do this to find every ORF starting with ATG, including ORFs which are located inside other ORFs.
        $ATG_count++;
        my $start = $-[0]+1;
        foreach (substr($genome,$-[0]) =~ m/^ATG(?:[ATGC]{3}){8,}(?:TAA|TAG|TGA)/ig) {
            my $length = $+[0];
            if ($length%3 == 0) {   ### I need to do this because sadly, the above regex DOESN'T recover only Strings are dividable by 3. (Why not?!?)
                my $stop = $start+$length;
                my $readingframe = ($start%3);
                push(@i, $start), push(@j, $stop), push(@l, $length), push (@frames, $readingframe);
                $ORF_count++;
            }
        }
    }

现在,上面的代码恢复以ATG开头的ORF,以(TAA | TAG | TGA)结束并且> = 30好 - 我试过了 - 但是恢复的ORFs有内部终止密码子!

我的问题是如何在ATG后第一个终止密码子处停止恢复的ORFs?我想一种可能性是从我的正则表达式的中间部分排除(TAA | TAG | TGA) - > (?:[ATGC]{3}){8,} 但是我该怎么做?

非常感谢提前!

编辑:

好的,在尝试了下面的建议之后,我想出了一个解决方案,它可以从给定的基因组序列中恢复所有重叠的ORFs> = 30 bp,从ATG开始并且没有内部终止密码子:

    my $genome = $_[0];
    my $ATG_count = 0;
    my $ORF_count = 0;
    my @i = (); 
    my @j = (); 
    my @l = (); 
    my @frames = (); 

    while ($genome =~ m/ATG/ig) {
        $ATG_count++;
        my $start = $-[0]+1;
        foreach (substr($genome,$-[0]) =~ m/^ATG(?:[ATGC]{3})*?(?:TAA|TAG|TGA)/ig) {    
        ### This was changed so that it matches "ATG - first(lazy) stop-codon". 
            my $length = $+[0];
            if ($length%3 == 0 && $length >=30) {    
            ### This was changed so that the matches must be >=30 in length.
                my $stop = $start+$length;
                my $readingframe = ($start%3);
                push(@i, $start), push(@j, $stop), push(@l, $length), push (@frames, $readingframe);
                $ORF_count++;
            }
        }
    }

3 个答案:

答案 0 :(得分:1)

您编写的模式将贪婪地搜索密码子,直到它到达字符串中的最终终止密码子。尝试重写你的模式:

m/ATG(?:[ATGC]{3}){8,}?(?:TAA|TAG|TGA)/ig

?添加到(?:[ATGC]{3}){8,}?告诉正则表达式引擎尽可能多地匹配密码子,直到第一个终止密码子,而不是最后一个。我也会从你的模式中省略^,假设起始密码子不是你序列中的第一个密码子。

至于确保返回的字符串不包含终止密码子,将结果包装在检查终止密码子的第二个正则表达式测试中。据我所知,在单一正则表达式模式中无法对此进行可变长度负面后视测试。

答案 1 :(得分:1)

尝试通过在其后面添加(?:[ATGC]{3}){8,}来使'重复'单元(?)非延迟:

^ATG(?:[ATGC]{3}){8,}?(?:TAA|TAG|TGA)
                     ^

在两个基因组上查看一个例子here,第一个在最后一个终止密码子之前使用终止密码子。

基本上,它会使'重复'单位的匹配最少,并且在第一个终止密码子处停止,不在最初的8个单位内。

现在,如果你想停止在这8个单位内的终止密码子,不要使用{8,},因为它意味着'至少8'。请改用+,表示“至少为1”或*表示至少为0.

^ATG(?:[ATGC]{3})+?(?:TAA|TAG|TGA)
                 ^

编辑:经过评论讨论后,结果还发现了ATGTAA这样的字符串,这意味着开始和结束密码子之间没有三元组。这就是说,使用上面提到的*将是正确的正则表达式:

^ATG(?:[ATGC]{3})*?(?:TAA|TAG|TGA)

答案 2 :(得分:0)

我刚刚在https://github.com/rstats-db/RSQLite/issues/101回答了这个问题。你需要的是一个消极的断言后视。它不必是可变宽度。来自另一篇文章:

m/ATG(?:[ATGC]{3}(?<!TAG|TAA|TGA)){8,}(?:TAG|TAA|TGA)/ig