2011-06-01 78 views
6

我一直在唬弄的頭髮30分鐘這樣一個團...正則表達式來代替%變量%

我有一本字典,像這樣:

{'search': 'replace', 
'foo': 'bar'} 

和一個字符串像這樣的:

Foo bar %foo% % search %. 

我想替換每個變量,它從字典相當於文本:

Foo bar bar replace. 

我現在正則表達式失敗,所以這裏是(keyvalue來自dictionary.items()):

re.sub(r'%\d+' + key + '[^%]\d+%', value, text) 

任何幫助,將不勝感激,因爲這正則表達式的東西我發瘋...

回答

8

如果你和你的字串你的語法靈活,Python有一個內置的機制,即:

>>> print 'Hello, %(your_name)s, my name is %(my_name)s' % {'your_name': 'Blender', 'my_name': 'Ken'} 
Hello, Blender, my name is Ken 

或者,如果你想要的是語法,我會避免重gular的表達式,只是這樣做:

>>> vars = {'search': 'replace', 
... 'foo': 'bar'} 
>>> mystring = "Foo bar %foo% % search %." 
>>> for k, v in vars.items(): 
...  mystring = mystring.replace('%%%s%%' % k, v) 
... 
>>> print mystring 
Foo bar bar % search %. 
+0

我不知道'%d'的東西可能需要變量名稱。謝謝。我可以做一個盲目的搜索和替換,但我也想佔空白(這就是爲什麼我嘗試正則表達式)。我會繼續擺弄它... – Blender 2011-06-01 19:57:41

+0

再次想到,'%'會很麻煩。我想我也會使用括號,因爲它更容易實施並且運作良好。任何方法我可以在最後省略'd'?我將它用於模板引擎,因此語法越簡單越好。 – Blender 2011-06-01 20:00:30

+0

您的替代方案無法正常工作。它可以做不想要的雙重內插。例如'{'foo':'%bar%','bar':'baz'}'。 @ murgatroid99的解決方案不受這個問題的影響。 – ikegami 2011-06-01 21:20:05

2

也許我失去了一些東西,但不會下面的正則表達式工作?

re.sub(r'%\s?' + key + '\s?%', value, text) 

唯一有點特別的是可選空格;它們可以與\s?匹配。

4

如果你想在一個聲明中,你可以做以下(假設s是字符串,d是字典):

re.sub(r"[%]\s*[^%]+\s*[%]",lambda k:d.get(k[1,-1].strip(),k),s) 

這將使用功能的更換零件來獲取每個值字典,並忽略它是否不在字典中。

編輯:修正了不必要的空格出現在查找鍵

2

使用替換功能支持的re.sub

def replace(s, kw, pattern=re.compile(r'%\s*(\w+)\s*%')): 
    """ 
    Replace delimited keys in a string with values from kw. 

    Any pattern may be used, as long as the first group defines the lookup key. 
    """ 
    lookup = lambda match: kw.get(match.group(1), match.group()) 
    return pattern.sub(lookup, s) 

>>> replace('Foo bar %foo% % search %.', {'search': 'replace', 'foo': 'bar'}) 
'Foo bar bar replace.' 

您可以更改lookup功能自定義錯誤如何查找被處理,等等。