2016-09-20 94 views
4

我需要找到匹配模式的所有字符串,但兩個給定字符串除外。正則表達式匹配除字符串外的所有字符

例如,找到除aabb之外的所有字母組。從這個字符串開始:

-a-bc-aa-def-bb-ghij- 

應返回:

('a', 'bc', 'def', 'ghij') 

我試着用this regular表達,抓住4串。我認爲我正在接近,但(1)它在Python中不起作用,(2)我無法弄清楚如何從搜索中排除幾個字符串。 (是的,我可以稍後刪除它們,但是我真正的正則表達式只能一次完成所有操作,我希望在其中包含最後一步。)

我說它在Python中不起作用,因爲我試過這個,期待完全相同的結果,而是我得到的只有第一組:

>>> import re 
>>> re.search('-(\w.*?)(?=-)', '-a-bc-def-ghij-').groups() 
('a',) 

我負嘗試一下未來,但我無法找到這種情況下,一個可行的解決方案。

+0

你想['findall'](https://docs.python.org/2/library/re.html#re.findall) - 'search'只能返回第一個匹配:) – cxw

回答

6

您可以使用負的樣子aheads的。

例如,

>>> re.findall(r'-(?!aa|bb)([^-]+)', string) 
['a', 'bc', 'def', 'ghij'] 

  • -相配-

  • (?!aa|bb)負先行,檢查是否-後面沒有aabb

  • ([^-]+)相配ONY或比其它多個字符-


編輯

上述正則表達式不匹配的那些,其與aabb啓動,例如像-aabc-。要照顧,我們可以添加-到喜歡向前看符號,

>>> re.findall(r'-(?!aa-|bb-)([^-]+)', string) 
+0

僅供參考:'(?!aa | bb)'lookahead不允許那些* aa或bb開頭的匹配項。所以說,'aacn' [不會匹配](https://regex101.com/r/jR5sH1/1)。 –

+0

@WiktorStribiżew有效點。我爲答案添加了一個編輯。感謝您指出:) – nu11p01n73R

+0

是的,我只是認爲最後的'-'實際上是必需的 - 只是由OP輸入字符串來判斷。如果最後沒有'-',你的正則表達式會返回一個匹配,我的不會。這一點尚不清楚,但我猜得到了一個倒退。 –

2

您需要使用負向前視來限制更一般的模式,並且需要使用re.findall來查找所有匹配項。

使用

res = re.findall(r'-(?!(?:aa|bb)-)(\w+)(?=-)', s) 

或 - 如果您在連字符之間的值可以是任何而是一個連字符,請使用否定的字符類[^-]

res = re.findall(r'-(?!(?:aa|bb)-)([^-]+)(?=-)', s) 

這裏是regex demo

詳細

  • - - 一個連字符
  • (?!(?:aa|bb)-) - 如果第一個連字符後aa-bb-,不匹配應退還
  • (\w+) - 第1組(該值將由re.findall呼叫返回)捕獲1個或更多字詞[^-]+ - 1個或更多字符除了-
  • (?=-) - 字符後面必須有一個-。在這裏需要預先保證重疊匹配(因爲這個連字符將成爲下一場比賽的起點)。

Python demo

import re 
p = re.compile(r'-(?!(?:aa|bb)-)([^-]+)(?=-)') 
s = "-a-bc-aa-def-bb-ghij-" 
print(p.findall(s)) # => ['a', 'bc', 'def', 'ghij'] 
+0

我會在這裏也加上這句話:我認爲最後一次比賽是必須的,因爲最後一場比賽只有跟着'-'纔有效。這是從OP字符串中推導出來的,所以不太確定。 –

0

雖然正則表達式溶液要求,我認爲這個問題可以用更簡單的Python函數,即字符串分割和過濾來解決簡單:

input_list = "-a-bc-aa-def-bb-ghij-" 
exclude = set(["aa", "bb"]) 
result = [s for s in input_list.split('-')[1:-1] if s not in exclude] 

此解決方案有額外的優點result也可以變成一臺發電機和結果列表並不需要顯式地構建。

相關問題