Python 搜索子字符串出现在具有负前瞻性的特定位置的字符串

Python 搜索子字符串出现在具有负前瞻性的特定位置的字符串,python,regex,negative-lookahead,Python,Regex,Negative Lookahead,我只是在尝试创建一个正则表达式时遇到了一个问题,它应该有助于查找包含特定子字符串组合的字符串 例如,我正在搜索子字符串组合: ab cd 1) “xxxabxxxxxxabxxxxcdxxx”->应为匹配项 2) “xxxabxxxxabxxxxabxxxxcdxxxx->无匹配项 3) “xxxabXXXXXXXXXXXXXcdXXXXX->不匹配 更为复杂的是: 4) “xxxabxxxxxabxxxxcdxxxabxxx->也应该是匹配项 我的子串组合也可以是这样: ab cd 或 ab

我只是在尝试创建一个正则表达式时遇到了一个问题,它应该有助于查找包含特定子字符串组合的字符串

例如,我正在搜索子字符串组合:

ab cd

1) “xxxabxxxxxxabxxxxcdxxx”->应为匹配项

2) “xxxabxxxxabxxxxabxxxxcdxxxx->无匹配项

3) “xxxabXXXXXXXXXXXXXcdXXXXX->不匹配

更为复杂的是:

4) “xxxabxxxxxabxxxxcdxxxabxxx->也应该是匹配项

我的子串组合也可以是这样:

ab cd

ab ab cd

ab cd ab cd

对于所有这些(以及更多)示例,我正在寻找一种系统化的方法来以系统化的方式构建相应的正则表达式,以便在子字符串以正确的顺序和频率出现的情况下,只找到匹配的字符串

我在“ab cd”子字符串搜索中得到了类似的结果,但在我的示例中,它失败了

p = re.compile("(?:(?!ab).)*ab.*?ab(?!.*ab).*cd",re.IGNORECASE)
在类似4)的情况下,此选项适用于,但也与类似2)的字符串匹配:

你能指出我的错误吗

非常感谢

编辑:

很抱歉,我的问题不够清楚。我试图把我的问题分解成一个更简单的案例,这可能不是个好主意。 下面是问题的详细说明:

我有一个(蛋白质)序列列表,并根据序列模式为每个序列指定一个特定类型

因此,我创建了一个字典,类型名称作为键,特征模板(特定顺序的序列特征列表)作为值,例如:

类型a->[a,a,B,C]

类型_b->[A、b、C]

类型c->[A,B,A,B]

另一方面,我对每个功能都有(简单的)正则表达式模式,例如:

A->[PHT]AG[QP]LI

B->RS[TP]电动汽车

C->

D->

现在,每个模板(type_a,type_b,…)都需要系统地构建连接的正则表达式模式(即对于type_a,构建搜索a,a,b,C的正则表达式)。 这将导致另一个dict,类型作为键,完整的正则表达式作为值

现在我想遍历序列列表中的每个序列,并将所有完整的正则表达式模板映射到每个序列。在最好的情况下,只有一个完整的正则表达式(type)应该与序列匹配

以上面的示例为例,具有以下正则表达式模板:

光盘

ab cd

ab cd

ab ab cd

ab cd ab cd

ab cd ab

“xxxabxxxxxxabxxxxcdxxx”

->这个序列应该匹配模板“ab cd”的正则表达式,而不是其他任何一个

使用下面的正则表达式,我可以完美地查找ab cd

p = re.compile("(?:(?!ab).)*ab.*?ab(?!.*ab).*cd",re.IGNORECASE)
如果我的测试是正确的,它将只匹配上面的序列1),而不是序列2)或3)

但是,如果我想搜索ab cd ab,则反向前瞻将不允许查找最后一个ab。我找到了类似于以下代码的内容,以在第二个“ab”部分之后中断反向前瞻。据我所知,反向前瞻应以“cd”停止,以便最后一个“ab”可以再次匹配

p = re.compile("(?:(?!ab).)*ab(?:(?!ab).)*ab((?!ab|cd)*).*cd", re.IGNORECASE)
它解决了ab-ab-cd-ab中最后一个“ab”的问题。 但不知何故,它现在不仅与“cd”(序列1)-ab-cd之前的2次“ab”匹配,而且与“cd”(序列2,ab-cd)之前的3次(或更多)的“ab”匹配,这是不应该的

我希望我的问题更清楚。非常感谢所有的答案,我将在明天回来工作时尝试代码。非常感谢您提供更多的答案,解释regex代码(我对regex非常陌生),并提供有关re.functions(匹配,最终…)的建议


谢谢

为什么你需要消极的前瞻? 为什么不使用这样简单的东西:

*ab.*ab.*cd
或者,如果需要从行的开头查找匹配项,可以使用:

^.*ab.*ab.*cd
编辑: 在你的评论之后,我明白了你的需要。试试这个:

^(?:(?!ab).)*ab(?:(?!ab).)*ab(?:(?!ab).)*cd

为什么你需要消极的前瞻? 为什么不使用这样简单的东西:

*ab.*ab.*cd
或者,如果需要从行的开头查找匹配项,可以使用:

^.*ab.*ab.*cd
编辑: 在你的评论之后,我明白了你的需要。试试这个:

^(?:(?!ab).)*ab(?:(?!ab).)*ab(?:(?!ab).)*cd

您可以使用
re.findall
并对其进行后期处理。实际上,您希望找到
ab
cd
的所有实例,并查看您的模式(
['ab','ab','cd']
)是否位于列表的开头。如下所示:

import re

test1 = "xxxabxxxxxxabxxxxcdxxx"
test2 = "xxxabxxxxabxxxxabxxxxcdxxxx"
test3 = "xxxabxxxxxxxxxxcdxxxx"
test4 = "xxxabxxxxxabxxxxcdxxxabxxx"

for x in (test1, test2, test3, test4):
    matches = re.findall(r'(ab|cd)', x)
    print matches[:3] == ['ab', 'ab', 'cd']
印刷品

True
False
False
True

根据需要。

您可以使用
re.findall
并对其进行后期处理。实际上,您希望找到
ab
cd
的所有实例,并查看您的模式(
['ab',ab',cd']
)是否位于列表的开头。以下内容:

import re

test1 = "xxxabxxxxxxabxxxxcdxxx"
test2 = "xxxabxxxxabxxxxabxxxxcdxxxx"
test3 = "xxxabxxxxxxxxxxcdxxxx"
test4 = "xxxabxxxxxabxxxxcdxxxabxxx"

for x in (test1, test2, test3, test4):
    matches = re.findall(r'(ab|cd)', x)
    print matches[:3] == ['ab', 'ab', 'cd']
印刷品

True
False
False
True

根据需要。

这匹配
xxxabxxxxabxxabxxxxcdxxxx
即使它不应该匹配。你能解释一下正则表达式吗?我对第一部分有问题,我想不是从ab开始的。(?:(!ab)。*关于正则表达式的解释:第一部分(?:(!ab)。)*查找任何不以ab开头的字符,然后查找ab,这会重复两次,然后再重复任何不以ab开头的字符,然后是cd。请参阅链接:@UriY:I尝试添加扩展正则表达式位:p=re.compile(^(?:(?!ab)。*ab(?(!ab)。*ab(?(!ab)。*(?:(!c)‌​d) )*cd(?(?!cd)*$‌​“,re.IGNORECASE。这应该匹配ab cd,但不是ab cd。但是,它不象字符串那样匹配mathc ab cd cd…这匹配
xxxabxxabxxabxxcdxxxx
即使它不应该匹配。你能在那里解释一下正则表达式它在做什么吗?我在第一部分遇到问题,不是从