2016-05-08 262 views
2

我在python中做了一個非常簡單的正則表達式,並且在使用「或」運算符時看到一些奇怪的行爲。Python中的正則表達式匹配

我試圖解析如下:

>> str = "blah [in brackets] stuff" 

,使其返回:

>> ['blah', 'in brackets', 'stuff'] 

要匹配括號內的文字,我使用的外觀後面,向前看,即:

>> '(?<=\[).*?(?=\])' 

如果單獨使用,確實可以捕獲括號中的文字:

>> re.findall('(?<=\[).*?(?=\])' , str) 
>> ['in brackets'] 

但是,當我結合或運營商來解析空間之間的字符串,支架匹配某種方式分解:

>> [x for x in re.findall('(?<=\[).*?(?=\])|.*?[, ]' , str) if x!=' ' ] 
>> ['blah', '[in ', 'brackets] '] 

對我的生活中,我無法理解這種行爲。任何幫助,將不勝感激。

謝謝!

+1

這可能幫助 - https://regex101.com/r/xM7sK0/1 - 左邊你可以進入調試器在那裏將說明如何它匹配了它所做的事情。 – TessellatingHeckler

+0

謝謝,這真的很有用。 – FrancisWolcott

+0

問題是正則表達式的後半部分也與括號相匹配。第一場比賽後(「blah」),剩餘的文字是[括號內]。正則表達式的前半部分在這裏不匹配,因爲向後看不到左括號。所以正則表達式的後半部分再次匹配並找到文本「[in」。 –

回答

2

你可以這樣做:

>>> s = "blah [in brackets] stuff" 

>>> re.findall(r'\b\w+\s*\w+\b', s) 
['blah', 'in brackets', 'stuff'] 
+0

謝謝!這是一個很好的解決方案。我仍然有興趣瞭解爲什麼我的工作無法正常進行......在我的腦海中逐步完成它是有道理的:嘗試匹配括號中的內容,如果不匹配,則匹配前面有空格的內容。對於我來說,or或者操作符的引入會打破括號匹配。有任何想法嗎? – FrancisWolcott

0

如果你正在尋找一種簡單的方法來做到這一點,然後用這個。 注:我用str替換了str,因爲'str'是python的一個內置函數。

import re 
string = "blah [in brackets] stuff" 
f = re.findall(r'\w+\w', string) 
print(f) 

輸出:[「括號」嗒嗒',「東西」]

0

答案爲止沒有考慮到,你可能有括號內超過2個字帳戶,甚至一個字。以下正則表達式將分割在括號和括號中的任何前導或尾隨空格上。如果字符串中有更多的括號內容,它也會工作。

s = "blah [in brackets] stuff" 

s = re.split(r'\s*\[|\]\s*', s) # note the 'or' operator is used and literal opening and closing brackets '\[' and '\]' 

print(s) 

輸出:['blah', 'in brackets', 'stuff']

以及使用與不同量的括號內詞語的字符串並且使用幾組括號的一個示例:

s = "blah [in brackets] stuff [three words here] more stuff [one-word] stuff [a digit 1!] stuff." 

s = re.split(r'\s*\[|\]\s*', s) 

print (s) 

輸出:['blah', 'in brackets', 'stuff', 'three words here', 'more stuff', 'one-word', 'stuff', 'a digit 1!', 'stuff.']

+0

我真的很喜歡你的解決方案。將其他分隔符與括號放在一組中也很容易。但唯一的一點是,它不會將多個單詞分割爲括號外的多個單詞,即它會返回「更多內容」而不是['more','stuff']。 – FrancisWolcott

2

對於那些有興趣的,這是我最終成功的正則表達式。有可能是一個更優雅的解決方案的地方,但這個工程:

>>> s = "blah 2.0 stuff 1 1 0 [in brackets] more stuff [1]" 

>>> brackets_re = '(?<=\[).*?(?=\])' 
>>> space_re = '[-\.\w]+(?=)' 
>>> my_re = brackets_re + '|' + space_re 

>>> re.findall(my_re, s) 
['blah', '2.0', 'stuff', '1', '1', '0', 'in brackets', 'more', 'stuff', '1'] 
+0

弗朗西斯做得很好 –