2012-10-31 41 views
0

我想寫一個正則表達式匹配的一系列文本的正則表達式查找和替換多個

[[any text or char her]] 

的所有情況。

如:

My name is [[Sean]] 
There is a [[new and cool]] thing here. 

這一切工作正常使用我的正則表達式。

data = "this is my tes string [[ that does some matching ]] then returns." 
p = re.compile("\[\[(.*)\]\]") 
data = p.sub('STAR', data) 

問題是,當我有匹配發生的歷史的多個實例:[[你好]]和[[再見]]

例如:

data = "this is my new string it contains [[hello]] and [[bye]] and nothing else" 
p = re.compile("\[\[(.*)\]\]") 
data = p.sub('STAR', data) 

這將匹配的開口支架你好,還有再見的左括號。我希望它能夠取代它們。

+2

你應該inlude在你的問題的標籤編程語言,使人們可以幫助你更好的。 –

回答

3

.*是貪婪的並且匹配儘可能多的文本,包括]][[,因此它通過您的「標籤」邊界進行處理。

一個快速的解決方案是讓明星慵懶加入了?

p = re.compile(r"\[\[(.*?)\]\]") 

一個更好的(更強大的和明確的,但速度稍慢)的解決方案是要清楚,我們不能在標籤邊界匹配:

p = re.compile(r"\[\[((?:(?!\]\]).)*)\]\]") 

說明:

\[\[  # Match [[ 
(   # Match and capture... 
(?:  # ...the following regex: 
    (?!\]\]) # (only if we're not at the start of the sequence ]] 
    .   # any character 
)*   # Repeat any number of times 
)   # End of capturing group 
\]\]  # Match ]] 
+0

n.b.提出的第二種方法會大大減緩正則表達式 –

+0

@BillyMoon:我只是'timeit.timeit()'編輯它。沒有太大區別(3.8微秒比4.2微秒,約10%)。 –

+0

非常感謝。我不使用正則表達式,所以第一個例子對我來說更易讀 - 因此更容易維護。 – Mark

2

+*使它匹配儘可能少的字符後,使用不符合匹配的.*? < ~~ ?。缺省情況是貪婪,並儘可能多地使用字符。

p = re.compile("\[\[(.*?)\]\]") 
1

您可以使用此:

p = re.compile(r"\[\[[^\]]+\]\]") 

>>> data = "this is my new string it contains [[hello]] and [[bye]] and nothing else" 
>>> p = re.compile(r"\[\[[^\]]+\]\]") 
>>> data = p.sub('STAR', data) 
>>> data 
'this is my new string it contains STAR and STAR and nothing else' 
+0

好主意,最好是最快的(我的機器3.2微秒,'。*?'3.8微秒)。唯一的缺點是單個右括號不能作爲匹配的一部分(在雙括號內),但這聽起來像是一個合理的折衷。 –