簡體   English   中英

在負位置提前搜索在特定位置出現子字符串的字符串

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

在嘗試創建正則表達式時,我只是面臨一個探查,它應該有助於查找包括子字符串的特定組合的字符串。

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

ab-ab-cd

1)“ xxx ab xxxxxx ab xxxx cd xxx”->應該匹配

2)“ xxx ab xxxx ab xxxx ab xxxx cd xxxx->沒有匹配項

3)“ xxx ab xxxxxxxxxx cd xxxx->沒有匹配項

使它更加復雜:

4)“ xxx ab xxxxx ab xxxx cd xxx ab xxx->也應匹配

我的子字符串組合也可能是這樣的:

A B C D

要么

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,B,C)。 然后,這將導致另一個類型為鍵,完整的正則表達式為值的字典。

現在,我想遍歷序列列表中的每個序列,並針對每個序列映射所有完整的正則表達式模板。 在最佳情況下,只有一個完整的正則表達式(類型)應與序列匹配。

從上面的示例中,具有以下正則表達式模板:

光盤

A B C D

ab-ab-cd

Ab-ab-ab-cd

ab-cd-ab-cd

ab-ab-cd-ab

“ xxx ab xxxxxx ab xxxx cd xxx”

->此序列應與模板“ 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”之前的2倍“ ab”匹配(序列1)-ab-ab-cd),而且還與“ cd”之前的3倍(ab)匹配(序列) 2,ab-ab-ab-cd),則不應這樣做。

我希望我的問題更加清楚。 非常感謝您提供的所有答案,明天我將在上班時嘗試該代碼。 任何進一步的答案都將受到高度贊賞,對正則表達式代碼的解釋(對正則表達式來說我還很陌生)以及使用re.functions(match,final ...)的建議。

謝謝

您可以使用re.findall並對其進行后處理。 實際上,您想查找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

按要求。

您為什么需要負面的展望? 為什么不使用那么簡單的東西:

*ab.*ab.*cd

或者,如果您需要它從行的開頭查找匹配項,則可以使用:

^.*ab.*ab.*cd

編輯:在您發表評論后,我了解了您的需求。 試試這個:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM