为什么re.findall在查找字符串中的三元组项时不具体。python

为什么re.findall在查找字符串中的三元组项时不具体。python,python,regex,string,findall,Python,Regex,String,Findall,我有四行代码 seq= 'ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA' OR_0 = re.findall(r'ATG(?:...){9,}?(?:TAA|TAG|TGA)',seq) 让我先解释一下我想做什么。如果这让人困惑,我很抱歉,但我会尽力解释 因此,我正在寻找以“ATG”开头的序列,后跟任何单词字符的3个单位[例如,“GGG”,“GTT”,“TTA”,等等],直到它遇到“TAA”,“TAG”或“TGA”,我还希望它们至少有30个字符

我有四行代码

seq= 'ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA'



OR_0 = re.findall(r'ATG(?:...){9,}?(?:TAA|TAG|TGA)',seq)  
让我先解释一下我想做什么。如果这让人困惑,我很抱歉,但我会尽力解释

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

这在某种程度上是可行的,但如果你注意到在序列中有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”< /P>。 如果以3为单位读取时,一个“ATG”后面跟着另一个“ATG”,那么这没关系,它不应该重新开始,但如果在以3为单位读取时遇到“TAA”、“TAG”或“TGA”,它应该停止

我的问题是,为什么re.findall会在ATG后面找到最长的“ATG”xxx-xxx-['TAA'、'TAG'或'TGA']序列,而不是在ATG后面第一次出现的“TAA'、'TAG'或'TGA'?


再一次,如果这让人困惑,我很抱歉,但是它会弄乱我基于这一行文本的多个数据集,我正在试图找出为什么不需要正则表达式

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,则返回值为:

ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA
ATGGAAGTTGGATGA
如果使用最小值0,则返回值为:

ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA
ATGGAAGTTGGATGA

你不需要正则表达式

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,则返回值为:

ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA
ATGGAAGTTGGATGA
如果使用最小值0,则返回值为:

ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA
ATGGAAGTTGGATGA

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

>>> import re
>>> seq= 'ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA'
>>> regex = re.compile(r'ATG(?:...)*?(?:TAA|TAG|TGA)')
>>> regex.findall(seq)
['ATGGAAGTTGGATGA']
无论如何,根据你的解释,我相信你以前的正则表达式实际上是在做你想做的事情:搜索至少30个字符的匹配项,这些字符从
ATG
开始,以
TGA
结束


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

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

>>> import re
>>> seq= 'ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA'
>>> regex = re.compile(r'ATG(?:...)*?(?:TAA|TAG|TGA)')
>>> regex.findall(seq)
['ATGGAAGTTGGATGA']
无论如何,根据你的解释,我相信你以前的正则表达式实际上是在做你想做的事情:搜索至少30个字符的匹配项,这些字符从
ATG
开始,以
TGA
结束

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

请尝试以下操作:

seq= 'ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA'
OR_0 = re.findall(r'ATG(?:.{3})*?(?:TAA|TAG|TGA)',seq) 
试试这个:

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

如果您希望您的正则表达式在第一个
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)
来确保三字符块在匹配三字符块之前不是
TAA | TAG | TGA

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

>>> re.findall(regexp, 'ATGAAAATAGAAAAAAAAAAAAAAAAAAAATAG')
['ATGAAAATAGAAAAAAAAAAAAAAAAAAAATAG']

如果您希望您的正则表达式在第一个
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)
来确保三字符块在匹配三字符块之前不是
TAA | TAG | TGA

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

>>> re.findall(regexp, 'ATGAAAATAGAAAAAAAAAAAAAAAAAAAATAG')
['ATGAAAATAGAAAAAAAAAAAAAAAAAAAATAG']

这适用于
ATG[ATG]{3}(.*?[ATG]
?要匹配到最新找到的字符串,应该是
ATG[ATG]{3}(.*[ATG]
,但是如果多次搜索该字符串,则需要特定的分隔符(如逗号或换行符)来知道结束位置。断线;不使用
DOTALL
/s
)就足够了。我希望你不是在从事基因专利业务。我不是在从事基因专利业务。我只是一名生物学学生,正在攻读生物信息学@ealfonsow。你所展示的输入的预期结果是什么?假设您得到的结果是正确的,因为任何其他匹配都太短。例如,根据您的描述(以及有关DNA的一些基本知识),对于您的样本输入,它不应返回任何结果。唯一有效的序列是
ATGGAAGTTGGATGA
(不能更长,因为它已被
TGA
终止),中间的部分只包含3个密码子(9个字符长)。这对
或_0
ATG[ATG]{3}(.?[ATG]
?要匹配到最新找到的字符串,应该是
ATG[ATG]{3}(.*[ATG]
,但是如果多次搜索该字符串,则需要特定的分隔符(如逗号或换行符)来知道结束位置。断线;不使用
DOTALL
/s
)就足够了。我希望你不是在从事基因专利业务。我不是在从事基因专利业务。我只是一名生物学学生,正在攻读生物信息学@ealfonsow。你所展示的输入的预期结果是什么?假设您得到的结果是正确的,因为任何其他匹配都太短。例如,根据您的描述(以及有关DNA的一些基本知识),对于您的样本输入,它不应返回任何结果。唯一有效的序列是
ATGGAAGT