2015-11-20 52 views
2

當替換本身是變量時,如何替換模式?使用python去除可變邊界

我有以下字符串:

s = '''[[merit|merited]] and [[eat|eaten]] and [[go]]''' 

我想(,「吃」,「去」值得')保留在括號中只有最右邊的字,剝離了什麼包圍這些詞語,從而產生:

merited and eaten and go

我有正則表達式:

p = '''\[\[[a-zA-Z]*\[|]*([a-zA-Z]*)\]\]'''

...主要生產:

>>> re.findall(p, s) 
['merited', 'eaten', 'go'] 

然而,由於這一變化,我不明白的方式來使用應用re.sub()或s.replace()。

+0

我不明白這個問題嗎?看起來正則表達式已經在做你想做的事情了?除非你想're.findall(p,s)[ - 1]'? – zwol

+0

對不起,不清楚。編輯了這個問題。 – zadrozny

+0

通過你的話只需在列表中循環,並保持通話re.findall – Illusionist

回答

4
s = '''[[merit|merited]] and [[eat|eaten]] and [[go]]''' 
p = '''\[\[[a-zA-Z]*?[|]*([a-zA-Z]*)\]\]''' 
re.sub(p, r'\1', s) 

?使得用於[[go]]第一[a-zA-Z]*將匹配空(最短)串和第二個將得到實際go

\1替代第一(在這種情況下,只有)匹配組中的圖案的每個非在字符串s中重疊匹配。 r'\1'用於使\1不與代碼爲0x1

+3

[正常運行](http://ideone.com/gNEqnr)。現在,請爲大家解釋一下。 –

+0

你能解釋r'\ 1'是如何工作的嗎? – zadrozny

4

那麼首先你需要修復你的正則表達式來捕捉整個集團解釋爲字符:

>>> s = '[[merit|merited]] and [[eat|eaten]] and [[go]]' 
>>> p = '(\[\[(?:[a-zA-Z]*\|)*([a-zA-Z]*)\]\])' 
>>> [('[[merit|merited]]', 'merited'), ('[[eat|eaten]]', 'eaten'), ('[[go]]', 'go')] 
[('[[merit|merited]]', 'merited'), ('[[eat|eaten]]', 'eaten'), ('[[go]]', 'go')] 

這符合整個[[whateverisinhere]]並分離了全場比賽爲1組,只是一錘定音爲組2.您可以使用比令牌\2只有2組更換整個比賽:

>>> re.sub(p,r'\2',s) 
'merited and eaten and go' 

或更改模式:

p = '\[\[(?:[a-zA-Z]*\|)*([a-zA-Z]*)\]\]' 

其擺脫分組整場比賽,你想要什麼1組,只有組。你可以這樣做:

>>> re.sub(p,r'\1',s) 

具有相同的效果。

POST編輯:

我忘了提,我居然改變了你的正則表達式所以這裏的解釋是:

\[\[(?:[a-zA-Z]*\|)*([a-zA-Z]*)\]\] 
\[\[       \]\] #literal matches of brackets 
    (?:   )* #non-capturing group that can match 0 or more of whats inside 
     [a-zA-Z]*\| #matches any word that is followed by a '|' character 
        (... ) #captures into group one the final word 

我覺得這是比你原來有什麼強大,因爲它也將發生變化如果有超過2個選項:

>>> s = '[[merit|merited]] and [[ate|eat|eaten]] and [[go]]' 
>>> p = '\[\[(?:[a-zA-Z]*\|)*([a-zA-Z]*)\]\]' 
>>> re.sub(p,r'\1',s) 
'merited and eaten and go' 
+0

我懷疑' '\ [\ [(:[A-ZA-Z] + \ |?)*([A-ZA-Z] +)\] \]''將是正則表達式更好,除非詞語可以實際上是零字母長? –

+0

好點,但它是安全匹配空虛沒有害處。匹配OP的內容,可能會出現零字,但永遠無法確定 –