为什么我的模式会产生这种结果?我希望它找到ATG
然后是3的序列,不包括TAA
。
In [102]: s = 'GATGCCTAAG'
In [103]: pat = re.compile("(ATG((\w\w\w)*)(?!TAA))")
In [104]: pat.findall(s)
Out[104]: [('ATGCCTAAG', 'CCTAAG', 'AAG')]
答案 0 :(得分:3)
findall
方法返回匹配列表。如果模式包含捕获组,则每个匹配都是模式中每个捕获组匹配的字符串的元组。
返回
pattern
中string
的所有非重叠匹配,作为字符串列表。从左到右扫描string
,并按找到的顺序返回匹配项。如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。结果中包含空匹配,除非它们触及另一场比赛的开头。
您的模式包含三个捕获组。这些组是嵌套的。第一个(也是最外面的)组是整个模式(ATG((\w\w\w)*)(?!TAA))
。第二组是((\w\w\w)*)
。第三组是(\w\w\w)
。
请注意,否定前瞻声明(?!TAA)
不是捕获组。
实质上,您的模式表示匹配密码子ATG
,然后是尽可能多的密码子,但如果匹配将停在TAA
密码子,则备份两个密码子。由于*
是贪婪的,因此您的模式将匹配中间的TAA
密码子。如果TAA
出现在输入字符串的末尾,它将仅拒绝TAA
密码子(以及之前的密码子)。
由于您的捕获组,您的模式表明每个返回的匹配应包含三个字符串:匹配密码子的完整序列,匹配密码子的序列(不包括初始ATG
)和序列中最后匹配的密码子
您可以使用(?:...)
将群组标记为非捕获,如下所示:
In [5]: pat = re.compile("(?:ATG(?:(?:\w\w\w)*)(?!TAA))")
如果您的模式不包含捕获组,则findall
将每个匹配作为单个字符串返回,而不是作为元组。
In [6]: pat.findall(s)
Out[6]: ['ATGCCTAAG']
如果您想停在第一个 TAA
,但如果根本没有TAA
,请转到字符串的末尾,您需要检查每个密码子,通过在重复中放置负面的先行断言:
pat = re.compile("ATG(?:(?!TAA)\w\w\w)*")
在初始ATG
之后的每个密码子处断言它不应与TAA
密码子匹配。
如果你想停在第一个TAA
密码子上,即使该密码子与ATG
不一致,你也可以这样做:
In [7]: pat = re.compile("ATG(?:(?!.{0,2}TAA)\w\w\w)*")
In [8]: pat.findall(s)
Out[8]: ['ATG']
In [10]: pat.findall('ATGCCTGAATATAAG')
Out[10]: ['ATGCCTGAA']
答案 1 :(得分:0)
此外,在re模块中,*除了@rob mayoff所写的内容之外,*可能包括该项目的零。
来自文档:
*
使得到的RE匹配0或更多次重复 在RE之前,尽可能多的重复。 ab *将匹配'a', 'ab'或'a'后跟任意数量的'b'。
答案 2 :(得分:0)
我认为你最好的解决方案是创建一个非常简单的正则表达式来捕获TAA,然后应用一个去除TAA模式的过滤器。