如何在正则表达式中使用布尔值或
How to use Boolean OR inside a regex
我想使用正则表达式查找一个子字符串,后跟可变数量的字符,然后是几个子字符串中的任意一个。
个 re.findall
"ATGTCAGGTAAGCTTAGGGCTTTAGGATT"
应该给我:
['ATGTCAGGTAA', 'ATGTCAGGTAAGCTTAG', 'ATGTCAGGTAAGCTTAGGGCTTTAG']
我尝试了以下所有方法均未成功:
import re
string2 = "ATGTCAGGTAAGCTTAGGGCTTTAGGATT"
re.findall('(ATG.*TAA)|(ATG.*TAG)', string2)
re.findall('ATG.*(TAA|TAG)', string2)
re.findall('ATG.*((TAA)|(TAG))', string2)
re.findall('ATG.*(TAA)|(TAG)', string2)
re.findall('ATG.*(TAA)|ATG.*(TAG)', string2)
re.findall('(ATG.*)(TAA)|(ATG.*)(TAG)', string2)
re.findall('(ATG.*)TAA|(ATG.*)TAG', string2)
我在这里错过了什么?
这不是超级简单,因为 a) 您想要重叠匹配,并且 b) 您想要贪婪和非贪婪以及介于两者之间的一切。
只要字符串比较短,你可以检查每个子字符串:
import re
s = "ATGTCAGGTAAGCTTAGGGCTTTAGGATT"
p = re.compile(r'ATG.*TA[GA]$')
for start in range(len(s)-6): # string is at least 6 letters long
for end in range(start+6, len(s)):
if p.match(s, pos=start, endpos=end):
print(s[start:end])
这会打印:
ATGTCAGGTAA
ATGTCAGGTAAGCTTAG
ATGTCAGGTAAGCTTAGGGCTTTAG
由于您似乎在处理 DNA 序列或类似的东西,请确保也检查一下 Biopython。
我非常喜欢接受的答案:-)也就是说,我添加这个是为了提供信息,而不是为了加分。
如果您对此非常需要,尝试对 O(N^2)
对索引进行匹配可能很快就会变得慢得无法忍受。一项改进是使用 .search()
方法直接 "leap" 到唯一可能获得回报的起始指数。所以下面这样做了。
它还使用 .fullmatch()
方法,这样您就不必人为更改 "natural" 正则表达式(例如,在您的示例中,无需添加尾随 $
到正则表达式 - 事实上,在下面的代码中这样做将不再按预期工作)。注意 .fullmatch()
是在 Python 3.4 中加入的,所以这段代码也需要 Python 3!
最后,这打算泛化re
模块的finditer()
function/method。虽然您不需要匹配对象(您只需要字符串),但它们的适用性要普遍得多,并且返回生成器通常也比返回列表更友好。
所以,不,这并不能完全满足您的需求,但可以得到您想要的东西,在 Python 3 中,速度更快:
def finditer_overlap(regexp, string):
start = 0
n = len(string)
while start <= n:
# don't know whether regexp will find shortest or
# longest match, but _will_ find leftmost match
m = regexp.search(string, start)
if m is None:
return
start = m.start()
for finish in range(start, n+1):
m = regexp.fullmatch(string, start, finish)
if m is not None:
yield m
start += 1
然后,例如,
import re
string2 = "ATGTCAGGTAAGCTTAGGGCTTTAGGATT"
pat = re.compile("ATG.*(TAA|TAG)")
for match in finditer_overlap(pat, string2):
print(match.group())
打印您在示例中想要的内容。您尝试编写正则表达式的其他方法也应该有效。在这个例子中它更快,因为第二次围绕外循环 start
是 1,并且 regexp.search(string, 1)
找不到另一个匹配项,所以生成器立即退出(所以跳过检查 O(N^2)
其他索引对)。
我想使用正则表达式查找一个子字符串,后跟可变数量的字符,然后是几个子字符串中的任意一个。
个 re.findall"ATGTCAGGTAAGCTTAGGGCTTTAGGATT"
应该给我:
['ATGTCAGGTAA', 'ATGTCAGGTAAGCTTAG', 'ATGTCAGGTAAGCTTAGGGCTTTAG']
我尝试了以下所有方法均未成功:
import re
string2 = "ATGTCAGGTAAGCTTAGGGCTTTAGGATT"
re.findall('(ATG.*TAA)|(ATG.*TAG)', string2)
re.findall('ATG.*(TAA|TAG)', string2)
re.findall('ATG.*((TAA)|(TAG))', string2)
re.findall('ATG.*(TAA)|(TAG)', string2)
re.findall('ATG.*(TAA)|ATG.*(TAG)', string2)
re.findall('(ATG.*)(TAA)|(ATG.*)(TAG)', string2)
re.findall('(ATG.*)TAA|(ATG.*)TAG', string2)
我在这里错过了什么?
这不是超级简单,因为 a) 您想要重叠匹配,并且 b) 您想要贪婪和非贪婪以及介于两者之间的一切。
只要字符串比较短,你可以检查每个子字符串:
import re
s = "ATGTCAGGTAAGCTTAGGGCTTTAGGATT"
p = re.compile(r'ATG.*TA[GA]$')
for start in range(len(s)-6): # string is at least 6 letters long
for end in range(start+6, len(s)):
if p.match(s, pos=start, endpos=end):
print(s[start:end])
这会打印:
ATGTCAGGTAA
ATGTCAGGTAAGCTTAG
ATGTCAGGTAAGCTTAGGGCTTTAG
由于您似乎在处理 DNA 序列或类似的东西,请确保也检查一下 Biopython。
我非常喜欢接受的答案:-)也就是说,我添加这个是为了提供信息,而不是为了加分。
如果您对此非常需要,尝试对 O(N^2)
对索引进行匹配可能很快就会变得慢得无法忍受。一项改进是使用 .search()
方法直接 "leap" 到唯一可能获得回报的起始指数。所以下面这样做了。
它还使用 .fullmatch()
方法,这样您就不必人为更改 "natural" 正则表达式(例如,在您的示例中,无需添加尾随 $
到正则表达式 - 事实上,在下面的代码中这样做将不再按预期工作)。注意 .fullmatch()
是在 Python 3.4 中加入的,所以这段代码也需要 Python 3!
最后,这打算泛化re
模块的finditer()
function/method。虽然您不需要匹配对象(您只需要字符串),但它们的适用性要普遍得多,并且返回生成器通常也比返回列表更友好。
所以,不,这并不能完全满足您的需求,但可以得到您想要的东西,在 Python 3 中,速度更快:
def finditer_overlap(regexp, string):
start = 0
n = len(string)
while start <= n:
# don't know whether regexp will find shortest or
# longest match, but _will_ find leftmost match
m = regexp.search(string, start)
if m is None:
return
start = m.start()
for finish in range(start, n+1):
m = regexp.fullmatch(string, start, finish)
if m is not None:
yield m
start += 1
然后,例如,
import re
string2 = "ATGTCAGGTAAGCTTAGGGCTTTAGGATT"
pat = re.compile("ATG.*(TAA|TAG)")
for match in finditer_overlap(pat, string2):
print(match.group())
打印您在示例中想要的内容。您尝试编写正则表达式的其他方法也应该有效。在这个例子中它更快,因为第二次围绕外循环 start
是 1,并且 regexp.search(string, 1)
找不到另一个匹配项,所以生成器立即退出(所以跳过检查 O(N^2)
其他索引对)。