Why is re.findall not being specific in finding triplet items in string. Python

后端 未结 4 946
故里飘歌
故里飘歌 2021-01-17 03:49

So I have four lines of code

seq= \'ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA\'



OR_0 = re.findall(r\'ATG(?:...){9,}?(?:TAA|TAG|TGA)\',seq)  
相关标签:
4条回答
  • 2021-01-17 04:08

    If the length is not a requirement then it's pretty easy:

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

    Anyway I believe, according to your explanation, that your previous regex is actually doing what you want: searching for matches of at least 30 characters that start in ATG and end in TGA.

    In your question you first state that you need matches of at least 30 characters, and hence you put the {9,}?, but after that you expect to match any match. You cannot have both, choose one. If length is important than keep the regex you already have and the result you are getting is correct.

    0 讨论(0)
  • 2021-01-17 04:09

    Try this:

    seq= 'ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA'
    OR_0 = re.findall(r'ATG(?:.{3})*?(?:TAA|TAG|TGA)',seq) 
    
    0 讨论(0)
  • 2021-01-17 04:25

    If you want your regex to stop matching at the first TAA|TAG|TGA, but still only succeed if there are at least nine three letter chunks, the following may help:

    >>> 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')
    []
    

    This uses a negative lookahead (?!TAA|TAG|TGA) to ensure that a three character chunk is not a TAA|TAG|TGA before it matches the three character chunk.

    Note though that a TAA|TAG|TGA that does not fall on a three character boundary will still successfully match:

    >>> re.findall(regexp, 'ATGAAAATAGAAAAAAAAAAAAAAAAAAAATAG')
    ['ATGAAAATAGAAAAAAAAAAAAAAAAAAAATAG']
    
    0 讨论(0)
  • 2021-01-17 04:25

    You don't need regular expressions.

    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
    

    If I use the min_len of 30, the return is:

    ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA
    

    If I use a min_len of 0, the return is:

    ATGGAAGTTGGATGA
    
    0 讨论(0)
提交回复
热议问题