2013-06-24 70 views
5

我試圖用正則表達式獲取括號外的任何文本。正則表達式獲取括號外的所有文本

例字符串

喬西史密斯[3996學報AVENUE,SOMETOWN,MD 21003] Mugsy狗史密斯 [2560 OAK ST,GLENMEADE,WI 14098]

我能夠方括號內的文字成功與:

addrs = re.findall(r"\[(.*?)\]", example_str) 
print addrs 
[u'3996 COLLEGE AVENUE, SOMETOWN, MD 21003',u'2560 OAK ST, GLENMEADE, WI 14098']  

但我無法在方括號外獲得任何以外的。我試着像下面這樣:

names = re.findall(r"(.*?)\[.*\]+", example_str) 

但只有發現的第一個名字:

print names 
[u'Josie Smith '] 

到目前爲止,我只看到了包含一到兩個name [address]連擊一個字符串,但我假設字符串中可以有任意數量的字符串。

+1

可以嵌套括號 – aaronman

+0

@aaronman我假設不會有任何嵌套括號。好問題。 – Banjer

回答

7

年底如果沒有嵌套的括號,你可以這樣做:

re.findall(r'(.*?)\[.*?\]', example_str) 

但是,你甚至不真的需要一個正則表達式,他回覆。只是劈在括號:

(s.split(']')[-1] for s in example_str.split('[')) 

唯一的原因,你的嘗試沒有成功:

re.findall(r"(.*?)\[.*\]+", example_str) 

是......你在做的括號內的非貪婪匹配,這意味着它正在捕獲從第一個開放式支架到最後一個緊湊式支架的所有內容,而不是僅捕獲第一對支架。


此外,+到底是錯誤的。如果您有​​,是否想要返回['abc ', '', ' jkl']['abc ', ' jkl']?如果是前者,請不要添加+。如果是後者,那麼 - 但是然後您需要將整個方括號內的模式置於非捕獲組中:r'(.*?)(?:\[.*?\])+


如果有可能是最後括號後附加文本,該split方法將正常工作,或者你可以使用re.split代替re.findall ......但如果你要調整你原來的正則表達式與工作,你可以。

在英文中,你想要的是任何(非貪婪)子字符串在括號內的子字符串字符串的末尾,對嗎?

所以,你需要在\[.*?\]$之間改變。當然,你需要將它分組以便編寫替代方案,而且你不想捕獲組。所以:

re.findall(r"(.*?)(?:\[.*?\]|$)", example_str) 
+0

如果在最後一對括號後有任何文本,該怎麼辦? (只提到你的正則表達式;你的分裂解決方案) –

+0

啊,是的,這一切都有道理。我更喜歡「分裂」解決方案。 – Banjer

+0

@TimPietzcker:您可以使用與OP原始正則表達式相同的樣式添加;有點複雜的是,編寫它的明顯方式需要一個非捕獲組。編輯答案顯示如何。 – abarnert

1

,你可以這樣做:

outside = re.findall(r"[^[]+(?=\[[^]]*]|$)", example_str) 

換句話說:所有不是左方括號後面括號裏面的東西或字符串

3

如果有從來沒有嵌套的括號:

([^[\]]+)(?:$|\[) 

例子:

>>> import re 
>>> s = 'Josie Smith [3996 COLLEGE AVENUE, SOMETOWN, MD 21003]Mugsy Dog Smith [2560 OAK ST, GLENMEADE, WI 14098]' 
>>> re.findall(r'([^[\]]+)(?:$|\[)', s) 
['Josie Smith ', 'Mugsy Dog Smith '] 

說明:

([^[\]]+) # match one or more characters that are not '[' or ']' and place in group 1 
(?:$|\[) # match either a '[' or at the end of the string, do not capture 
+0

這個效果更好,因爲它不會像@ abamert's那樣返回空字符串 –

1

如果你想要去的正則表達式,仍然處理嵌套括號,你可以使用:

import re 
expr = re.compile("(?:^|])([^[\]]+)(?:\[|$)") 

print(expr.findall("myexpr[skip this[and this]]another[and skip that too]")) 

這將產生['myexpr', 'another']

這個想法是匹配字符串的開始或]和字符串的結尾或[之間的任何內容。

相關問題