使用匹配的模式将模板字符串替换为dict的索引



我正在尝试用另一个dict中可用的值替换模板字符串。我知道如何使用.findall然后使用.replace来完成此操作,但我试图将其转换为一个操作。

这就是我尝试的:

import re
p = r'{{(w+?)}}'
g = {'call':'CALL', 'ball':'BALL'}
s = 'This was the day I would {{call}} and play {{ball}} with my {{dog}}'
a = re.sub(p, g.get('{}'.format(r'1'),'NONE'), s)
print(a)

我预期:

This was the day I would CALL and play BALL with my NONE

但我得到了:

This was the day I would NONE and play NONE with my NONE

我们可以不像我那样使用匹配的字符串1吗?

编辑:较大问题说明:(针对Hagai的注释(

给定一个字符串;占位符";,替换dict中的值。示例:

'Dear {{FirstName}} your {{Vehicle}} has been impounded. Please call {{TowingService}} for more details. Thanks for reading, {{FirstName}}!'

何处

dict = { 'AcctId':921103,
'FirstName': 'Buzz', 
'LastName': 'LightYear',
'Address': 'Milkyway',
'TowingService': 'Darknot',
'Vehicle': 'Mazda'
}

换句话说,我们不知道将使用哪些模板变量,它的顺序是什么,以及它们将重复多少次。

如果不进一步解释为什么需要使用regex,在我看来这是一个大材小用
使用内置的str方法str.format
该代码看起来像:

s.format(**g)

如果您也有一些占位符,您希望它们具有默认值(例如dog->NONE(,则使用regex查找所有占位符,然后将它们全部添加到默认dict中。
这看起来像:

pattern = "{(.*?)}"
found = re.findall(pattern, s)
for fill in found:
g[fill] = "NONE"
s.format(**g)

更新:
就我个人而言,我最喜欢使用重新打包,因为它的执行时间几乎总是更长,尤其是对于较长的字符串
看到你的答案,很喜欢,所以投票支持

专家问题更新:
如果您使用的是python 3.2+,最简单的解决方案是使用str.format_map
是这样的:

class Formatter(dict):
def __missing__(self, key):
return "Oh no!"
"an {a} with some {b} and a {c}".format_map(Formatter(a="eagle", b="fish"))
>>> "and eagle with some fish and a Oh no!"

注意:

  1. 在这个简单的解决方案中,不需要解压缩Formatter类(它基本上是一个带有__missing__方法的dict(
  2. 您可以使用Formatter类内联包装现有dict,这样您就不需要更改现有代码:Formatter(existing_dict)将完美工作
  3. 如果您被迫使用双花括号({{some-string}}(,那么您可以链接该方法。比如:
"an {{a}} with some {{b}} and a {{c}}"
.format_map(Formatter(a="eagle", b="fish"))
.format_map(Formatter(a="eagle", b="fish"))

如果在python 3.2下,我建议使用我第一次写的答案,因为如果字符串中有一些参数而不是dict中的参数,它会找到并更新(这会导致KeyError(。对于dict的内容超过字符串所需内容的情况,也就是说,你不需要做任何事情,str.format会完全忽略它

啊,多亏了这个SO答案,当以这种方式使用r'1'时,它看起来像是作为字符串传递的。

以这种方式返工可以按预期工作:

import re
p = r'{{(w+?)}}'
g = {'call':'CALL', 'ball':'BALL'}
s = 'This was the day I would {{call}} and play {{ball}} with my {{dog}}'
a = re.sub(p, lambda m: g.get(m.group(1), 'NONE'), s)
print(a)

输出:

This was the day I would CALL and play BALL with my NONE

最新更新