搜索字符串,其中子字符串出现在特定位置,具有负面前瞻性

Searching strings where substring occur at specific positions with negative look-ahead

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

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

ab-ab-cd

1) "xxxabxxxxxxabxxxxcdxxx" -> 应该匹配

2) "xxxabxxxxabxxxxabxxxx cdxxxx -> 不匹配

3) "xxxabxxxxxxxxxxcdxxxx -> 不匹配

让它变得更复杂:

4) "xxxabxxxxxabxxxxcdxxx abxxx -> 也应该匹配

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

ab-cd

ab-ab-ab-cd

ab-cd-ab-cd

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

我在 "ab-ab-cd" 子字符串搜索中得到了类似的结果,但在我的示例 4) 中它失败了。

p = re.compile("(?:(?!ab).)*ab.*?ab(?!.*ab).*cd",re.IGNORECASE)

在像 4) 这样的情况下,这个可以工作,但也匹配像 2) 这样的字符串:

p = re.compile("(?:(?!ab).)*ab(?:(?!ab).)*ab((?!ab|cd)*).*cd", re.IGNORECASE)

你能指出我的错误吗?

非常感谢!

编辑:

对不起大家,我的问题不够清楚。我试图将我的问题分解为一个更简单的案例,这可能不是个好主意。 问题的详细解释来了:

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

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

type_a -> [A,A,B,C]

type_b -> [A,B,C]

type_c -> [A,B,A,B]

在其他词典中,我为每个功能设置了(简单的)正则表达式模式,例如:

A -> [PHT]AG[QP]LI

B -> RS[TP]EV

C -> ...

D -> ...

现在每个模板 (type_a, type_b,...) 我现在系统地构建连接的正则表达式模式(即 type_a 构建一个正则表达式搜索 A,A ,公元前)。 这将导致另一个字典以类型为键,完整的正则表达式为值。

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

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

光盘

ab-cd

ab-ab-cd

ab-ab-ab-cd

ab-cd-ab-cd

ab-ab-cd-ab

"xxxabxxxxxxabxxxxcdxxx"

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

使用以下正则表达式我可以完美地查找 ab-ab-cd。

p = re.compile("(?:(?!ab).)*ab.*?ab(?!.*ab).*cd",re.IGNORECASE)

如果我的测试是正确的,它只会匹配上面的序列 1) 而不是 2) 或 3)。

但是,如果我想搜索 ab-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-ab-cd)之前的 2 次 "ab",而且匹配之前的 3 次(或更多次)"ab" "cd"(序列 2,ab-ab-ab-cd),它不应该。

希望我的问题更清楚。非常感谢所有的答案,明天我回去工作时会尝试代码。非常感谢任何进一步的答案,正则表达式代码的解释(我对正则表达式很陌生)和使用 re.functions(匹配,最终...)的建议。

谢谢

为什么需要负面展望? 为什么不用这么简单的东西:

*ab.*ab.*cd

或者如果你需要它从行首开始匹配,你可以使用:

^.*ab.*ab.*cd

编辑: 在您发表评论后,我明白了您的需求。试试这个:

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

您可以使用 re.findall 和 post 对其进行处理。实际上,您想找到 abcd 的所有实例,并查看您的模式 (['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

根据需要。