Python 重叠正则表达式匹配

Python 重叠正则表达式匹配,python,regex,overlapping-matches,Python,Regex,Overlapping Matches,我正在尝试创建以下正则表达式:从以下RNA字符串中返回一个介于AUG和(UAG或UGA或UAA)之间的字符串:agccauguagcuacuacagagguaguaggauggagacccagagcuugauguaguagaugugugugugugauguagcugaugugugaugg,以便找到所有匹配项,包括重叠的部分 我试过几个正则表达式,结果是这样的: matches = re.findall('(?=AUG)(\w+)(?=UAG|UGA|UAA)',"AGCCAUGUAGCUAACU

我正在尝试创建以下正则表达式:从以下RNA字符串中返回一个介于
AUG
和(
UAG
UGA
UAA
)之间的字符串:
agccauguagcuacuacagagguaguaggauggagacccagagcuugauguaguagaugugugugugugauguagcugaugugugaugg
,以便找到所有匹配项,包括重叠的部分

我试过几个正则表达式,结果是这样的:

matches = re.findall('(?=AUG)(\w+)(?=UAG|UGA|UAA)',"AGCCAUGUAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAAUGAUCCGAGUAGCAUCUCAG")

你能告诉我正则表达式模式中的错误吗?

用一个正则表达式执行此操作实际上相当困难,因为大多数用法都不希望重叠匹配。但是,您可以通过一些简单的迭代来实现这一点:

regex = re.compile('(?=AUG)(\w+)(?=UAG|UGA|UAA)');
RNA = 'AGCCAUGUAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAAUGAUCCGAGUAGCAUCUCAG'
matches = []
tmp = RNA
while (match = regex.search(tmp)):
    matches.append(match)
    tmp = tmp[match.start()-2:]  #Back up two to get the UG portion.  Shouldn't matter, but safer.

for m in matches:
    print m.group(0)
不过,这也有一些问题。如果是
auguaguaaa
,您希望回报是什么?有两个字符串要返回吗?还是只有一个?现在,正则表达式甚至不能捕获
UAG
,因为它会继续匹配
UAGUGA
,并在
UAA
处被截断。为了解决这个问题,您可能希望使用
操作符使您的操作符变懒-这种方法将无法捕获较长的子字符串

也许对字符串进行两次迭代就是答案,但是如果您的RNA序列包含
augauguaa
?那里的正确行为是什么

我可能倾向于采用无正则表达式的方法,通过迭代字符串及其子字符串:

RNA = 'AGCCAUGUAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAAUGAUCCGAGUAGCAUCUCAG'
candidates = []
start = 0

while (RNA.find('AUG', start) > -1):
    start = RNA.find('AUG', start) #Confound python and its lack of assignment returns
    candidates.append(RNA[start+3:])
    start += 1

matches = []

for candidate in candidates:
    for terminator in ['UAG', 'UGA', 'UAA']:
        end = 1;
        while(candidate.find(terminator, end) > -1):
            end = candidate.find(terminator, end)
            matches.append(candidate[:end])
            end += 1

for match in matches:
    print match
这样,无论发生什么情况,你都能得到所有的匹配项

如果需要跟踪每个匹配的位置,可以修改候选数据结构以使用元组来保持起始位置:

RNA = 'AGCCAUGUAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAAUGAUCCGAGUAGCAUCUCAG'
candidates = []
start = 0

while (RNA.find('AUG', start) > -1):
    start = RNA.find('AUG', start) #Confound python and its lack of assignment returns
    candidates.append((RNA[start+3:], start+3))
    start += 1

matches = []

for candidate in candidates:
    for terminator in ['UAG', 'UGA', 'UAA']:
        end = 1;
        while(candidate[0].find(terminator, end) > -1):
            end = candidate[0].find(terminator, end)
            matches.append((candidate[1], candidate[1] + end, candidate[0][:end]))
            end += 1

for match in matches:
    print "%d - %d: %s" % match
其中打印:

7 - 49: UAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAU
7 - 85: UAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAAUGAUCCGAG
7 - 31: UAGCUAACUCAGGUUACAUGGGGA
7 - 72: UAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCC
7 - 76: UAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAA
7 - 11: UAGC
7 - 66: UAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAA
27 - 49: GGGAUGACCCCGCGACUUGGAU
27 - 85: GGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAAUGAUCCGAG
27 - 31: GGGA
27 - 72: GGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCC
27 - 76: GGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAA
27 - 66: GGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAA
33 - 49: ACCCCGCGACUUGGAU
33 - 85: ACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAAUGAUCCGAG
33 - 72: ACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCC
33 - 76: ACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAA
33 - 66: ACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAA
78 - 85: AUCCGAG
见鬼,再加上三行,你甚至可以根据它们在RNA序列中的位置对匹配进行排序:

from operator import itemgetter
matches.sort(key=itemgetter(1))
matches.sort(key=itemgetter(0)) 
放置在最终打印之前的内容将使您:

007 - 011: UAGC
007 - 031: UAGCUAACUCAGGUUACAUGGGGA
007 - 049: UAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAU
007 - 066: UAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAA
007 - 072: UAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCC
007 - 076: UAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAA
007 - 085: UAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAAUGAUCCGAG
027 - 031: GGGA
027 - 049: GGGAUGACCCCGCGACUUGGAU
027 - 066: GGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAA
027 - 072: GGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCC
027 - 076: GGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAA
027 - 085: GGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAAUGAUCCGAG
033 - 049: ACCCCGCGACUUGGAU
033 - 066: ACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAA
033 - 072: ACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCC
033 - 076: ACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAA
033 - 085: ACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAAUGAUCCGAG
078 - 085: AUCCGAG

不幸的是,
re
模块目前不支持重叠匹配,但您可以很容易地将解决方案分解如下:

'AGCCAUGUAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAAUGAUCCGAGUAGCAUCUCAG'
matches = []

for m in re.finditer('AUG', str):
    for n in re.finditer('(UAG)|(UGA)|(UAA)', str[m.start():]):
        matches.append(str[m.start()+3:m.start()+n.end()-3]

print matches

如果你不考虑“比赛”,而是考虑“间隔”,我想你会发现这更容易。这就是@ionut hulub所做的。正如我在下面演示的,您可以在一次传递中完成,但是您可能应该使用更简单的finditer()方法,除非您有足够的RNA字符串(或者它们足够长),您需要避免对字符串进行冗余传递

s = 'AGCCAUGUAGCUAACUCAGGUUACAUGGGGAUGACCCCGCGACUUGGAUUAGAGUCUCUUUUGGAAUAAGCCUGAAUGAUCCGAGUAGCAUCUCAG'

def intervals(s):
    state = []
    i = 0
    max = len(s) - 2
    while i < max:
        if s[i] == 'A' and s[i+1] == 'U' and s[i+2] == 'G':
            state.append(i)
        if s[i] == 'U' and (s[i+1] == 'A' and s[i+2] == 'G') or (s[i+1] == 'G' and s[i+2] == 'A') or (s[i+1] == 'A' and s[i+2] == 'A'):
            for b in state:
                yield (b, i)
        i += 1

for interval in intervals(s):
    print interval
s='AGCCAUGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAGUAG'
def间隔:
状态=[]
i=0
最大值=透镜(s)-2
而我
我以前回答过一个类似的问题:不能使用Python regex afaik。在Perl中,您可以通过一些技巧获得所有可能的匹配。有一种方法允许重叠匹配。也许我错了,但我认为您的意思是:
在re.finditer('(UAG)|(UGA)|(UAA);(UAA);(UAA);(n.group()):
@FrankieTheKneeMan:不是真的,但我确实犯了一个错误。谢谢你让我知道。正则表达式库允许使用“重叠”标志进行重叠匹配。