0

所以我有四行代码

seq= 'ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA'



OR_0 = re.findall(r'ATG(?:...){9,}?(?:TAA|TAG|TGA)',seq)  

让我先解释一下我要做什么。. . 如果这令人困惑,我很抱歉,但我会尽力解释它。

所以我正在寻找以'ATG'开头的序列,后跟任何单词字符的3个单位[例如'GGG','GTT','TTA'等],直到它遇到'TAA','TAG'或“TGA”我还希望它们至少有 30 个字符长。. . 因此 {9,}?

这在某种程度上有效,但如果你注意到在seq中有ATG GAA GTT GGA TGA AAG TGG AGG TAA AGA GAA GAC GTT TGA

所以在这种情况下,如果它从第一个 'ATG' 开始并一直到下一个'TAA'、'TAG' 或 'TGA',它应该找到 'ATGGAAGTTGGATGA '

但是,当您运行 OR_0 代码行时,它会吐出整个 seq 字符串。我不知道如何让它只考虑第一个'TAA','TAG'或'TGA',然后是第一个'ATG'

如果在以 3 为单位读取时,“ATG”后面跟着另一个“ATG”,那没关系,它不应该重新开始,但如果在以 3 为单位读取时遇到“TAA”、“TAG”或“TGA”它应该停止。

我的问题,为什么 re.findall 会找到最长的 'ATG'xxx-xxx-['TAA','TAG' or 'TGA'] 序列,而不是第一次出现的 'TAA','TAG' 或 'TGA'在以 3 为单位的单词字符分隔的 ATG 之后?

再一次,如果这令人困惑,我深表歉意,但它弄乱了我基于此初始文本行的多个数据集,我正试图找出原因

4

4 回答 4

2

如果您希望您的正则表达式在第一个停止匹配TAA|TAG|TGA,但仍然只有在至少有九个三字母块时才能成功,以下可能会有所帮助:

>>> import re
>>> regexp = r'ATG(?:(?!TAA|TAG|TGA)...){9,}?(?:TAA|TAG|TGA)'
>>> re.findall(regexp, 'ATGAAAAAAAAAAAAAAAAAAAAAAAAAAATAG')
['ATGAAAAAAAAAAAAAAAAAAAAAAAAAAATAG']
>>> re.findall(regexp, 'ATGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATAG')
['ATGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATAG']
>>> re.findall(regexp, 'ATGAAATAGAAAAAAAAAAAAAAAAAAAAATAG')
[]

这使用负前瞻(?!TAA|TAG|TGA)来确保三字符块在匹配三字符块之前不是a 。TAA|TAG|TGA

请注意TAA|TAG|TGA落在三个字符边界上的 a 仍将成功匹配:

>>> re.findall(regexp, 'ATGAAAATAGAAAAAAAAAAAAAAAAAAAATAG')
['ATGAAAATAGAAAAAAAAAAAAAAAAAAAATAG']
于 2013-04-28T08:44:00.907 回答
1

如果长度不是要求,那么这很容易:

>>> import re
>>> seq= 'ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA'
>>> regex = re.compile(r'ATG(?:...)*?(?:TAA|TAG|TGA)')
>>> regex.findall(seq)
['ATGGAAGTTGGATGA']

无论如何,根据您的解释,我相信您以前的正则表达式实际上正在做您想做的事情:搜索至少 30ATG个以TGA.

在您的问题中,您首先声明您需要至少 30 个字符的匹配项,因此您放置了{9,}?, 但之后您希望匹配任何匹配项。你不能两者兼得,选择一个。如果长度比保留您已有的正则表达式更重要,并且您得到的结果是正确的

于 2013-04-28T08:36:53.397 回答
0

尝试这个:

seq= 'ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA'
OR_0 = re.findall(r'ATG(?:.{3})*?(?:TAA|TAG|TGA)',seq) 
于 2013-04-28T08:40:21.370 回答
0

你不需要正则表达式。

def chunks(l, n):
    """ Yield successive n-sized chunks from l.
    from: http://stackoverflow.com/a/312464/1561176
    """
    for i in xrange(0, len(l), n):
        yield l[i:i+n]

def method(sequence, start=['ATG'], stop=['TAA','TAG','TGA'], min_len=30):
    response = ''
    started = False
    for x in chunks(sequence, 3):
        if x in start:
            started = True
            response += x
        elif x in stop and started:
            if len(response) >= min_len:
                yield response + x
                response = ''
                started = False
            else:
                response += x
        elif started:
            response += x
    yield response

for result in method('ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA'):
    print result

如果我使用 30 的 min_len,则返回:

ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA

如果我使用 0 的 min_len,则返回为:

ATGGAAGTTGGATGA
于 2013-04-28T08:25:15.680 回答