![](/img/trans.png)
[英]Python regex: Negative look-ahead with selection of different length strings
[英]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
並對其進行后處理。 實際上,您想查找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
按要求。
您為什么需要負面的展望? 為什么不使用那么簡單的東西:
*ab.*ab.*cd
或者,如果您需要它從行的開頭查找匹配項,則可以使用:
^.*ab.*ab.*cd
編輯:在您發表評論后,我了解了您的需求。 試試這個:
^(?:(?!ab).)*ab(?:(?!ab).)*ab(?:(?!ab).)*cd
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.