首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >regex负前瞻性断言似乎不起作用

regex负前瞻性断言似乎不起作用
EN

Stack Overflow用户
提问于 2013-11-14 23:11:44
回答 3查看 245关注 0票数 0

为什么我的模式会产生这样的结果?我希望它能找到ATG,然后是一个不包括TAA的3序列。

代码语言:javascript
复制
In [102]: s = 'GATGCCTAAG'
In [103]: pat = re.compile("(ATG((\w\w\w)*)(?!TAA))")
In [104]: pat.findall(s)
Out[104]: [('ATGCCTAAG', 'CCTAAG', 'AAG')]
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-11-14 23:15:19

findall方法返回匹配的列表。如果模式包含捕获组,那么每个匹配都是模式中每个捕获组匹配的字符串的一个元组。

来自文献资料

返回patternstring中的所有不重叠匹配,作为字符串列表。string由左向右扫描,并按找到的顺序返回匹配。如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,则这将是一个元组列表。结果中包含空匹配,除非它们触及另一个匹配的开始。

您的模式包含三个捕获组。这些组是嵌套的。第一个(和最外层)组是整个模式,(ATG((\w\w\w)*)(?!TAA))。第二组为((\w\w\w)*)。第三组为(\w\w\w)

注意,负前瞻性断言(?!TAA)而不是,它是一个捕获组。

本质上,您的模式是匹配密码子ATG,后面跟着尽可能多的密码子,但是如果匹配将在TAA密码子处停止,则备份两个密码子。由于*是贪婪的,您的模式将匹配中间的TAA密码子。只有当TAA发生在输入字符串的末尾时,它才会拒绝一个TAA密码子(以及之前的密码子)。

由于捕获组,您的模式要求每个返回的匹配应该包含三个字符串:整个匹配密码子序列、不包括初始ATG的匹配密码子序列以及序列中的最后匹配密码子。

可以使用(?:...)将组标记为非捕获,如下所示:

代码语言:javascript
复制
In [5]: pat = re.compile("(?:ATG(?:(?:\w\w\w)*)(?!TAA))")

如果您的模式不包含捕获组,那么findall以单个字符串而不是元组的形式返回每个匹配。

代码语言:javascript
复制
In [6]: pat.findall(s)
Out[6]: ['ATGCCTAAG']

如果您想在first TAA停下来,但是如果根本没有TAA,则转到字符串的末尾,您需要检查每个密码子,方法是在重复中放置您的负查找断言:

代码语言:javascript
复制
pat = re.compile("ATG(?:(?!TAA)\w\w\w)*")

这表明,在初始ATG之后的每个密码子上,它不应该与TAA密码子匹配。

如果您想在第一个TAA密码子处停止,即使该密码子与ATG不对齐,您也可以这样做:

代码语言:javascript
复制
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']
票数 3
EN

Stack Overflow用户

发布于 2013-11-14 23:19:31

另外,在re模块中,*除了@rob所写的内容外,还可能包含该项目的零项。

从医生那里:

代码语言:javascript
复制
*

使结果RE与前面RE的0或更多重复匹配,尽可能多重复。ab*将匹配“a”、“ab”或“a”,后面跟着任意数目的“b”。

票数 0
EN

Stack Overflow用户

发布于 2013-11-14 23:22:39

我认为您最好的解决方案是创建一个非常简单的正则表达式来捕获TAA,然后应用一个筛选器来去除TAA模式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19990379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档