用正则替换%变量%

7 投票
4 回答
7628 浏览
提问于 2025-04-16 18:47

我已经为这个问题抓狂了30分钟...

我有一个字典,长得像这样:

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

还有一个字符串,像这样:

Foo bar %foo% % search %.

我想把每个变量替换成字典里对应的文本:

Foo bar bar replace.

我现在的正则表达式不管用,所以这是我写的(keyvalue是从dictionary.items()里来的):

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

如果有人能帮忙就太好了,因为这些正则表达式真让我抓狂...

4 个回答

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 函数,来定制如何处理查找错误等等。

4

如果你想用一句话来实现这个功能,可以这样做(假设 s 是字符串,d 是字典):

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

这里在替换的部分使用了一个函数,从字典中获取每个值,如果字典里没有这个值就会被忽略。

编辑:修复了在查找键时出现多余空格的问题。

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

另外,如果你想使用那种写法,我建议不要用正则表达式,直接这样做就可以了:

>>> 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 %.

撰写回答