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

Python 使用匹配的模式作为索引将模板字符串替换为dict,python,Python,我正在尝试用另一个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('{}'.fo

我正在尝试用另一个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中的值。 例如:

在哪里

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

啊,多亏了,当以这种方式使用
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
啊,多亏了,看起来当以这种方式使用
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

没有进一步解释为什么需要使用正则表达式,我觉得这是一个很大的过度使用。
使用内置的
str
方法
str.format

该代码如下所示:

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

s.format(**g)
如果您还需要一些占位符作为默认值(例如dog->NONE),则使用regex查找所有占位符,然后将它们全部添加到默认dict中。
这看起来像:

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

s.format(**g)
更新:
就我个人而言,我更喜欢尽可能少地使用重新打包,因为它的执行时间几乎总是更长,尤其是对于更长的字符串。
我看到你的答案,非常喜欢

扩展问题更新:
如果您使用的是python 3.2+,最简单的解决方案是使用 事情是这样的:

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!"
请注意:

  • 在这个简单的解决方案中,不需要解包格式化程序类(它基本上是一个带有
    \uuuuu missing\uuuu
    方法的dict)
  • 您可以将现有dict与Formatter类内联,这样您就不需要更改现有代码:
    Formatter(existing_dict)
    可以很好地工作
  • 如果您被迫使用双圆括号(
    {{some string}}
    )执行操作,则可以链接该方法。比如:


  • 如果在Python3.2下,那么我建议使用我第一次编写的答案,因为如果字符串中有一些参数,而dict中没有这些参数(这将导致
    KeyError
    ),它将查找并更新这些参数。对于dict的内容超过字符串所需的内容的情况,即您不需要做任何事情,
    str.format
    将简单地忽略它,而不进一步解释为什么需要使用regex,在我看来,这似乎是一个很大的过度使用。
    使用内置的
    str
    方法
    str.format

    该代码如下所示:

    s.format(**g)
    
    pattern = "{(.*?)}"
    found = re.findall(pattern, s)
    for fill in found:
       g[fill] = "NONE"
    
    s.format(**g)
    
    如果您还需要一些占位符作为默认值(例如dog->NONE),则使用regex查找所有占位符,然后将它们全部添加到默认dict中。
    这看起来像:

    s.format(**g)
    
    pattern = "{(.*?)}"
    found = re.findall(pattern, s)
    for fill in found:
       g[fill] = "NONE"
    
    s.format(**g)
    
    更新:
    就我个人而言,我更喜欢尽可能少地使用重新打包,因为它的执行时间几乎总是更长,尤其是对于更长的字符串。
    我看到你的答案,非常喜欢

    扩展问题更新:
    如果您使用的是python 3.2+,最简单的解决方案是使用 事情是这样的:

    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!"
    
    请注意:

  • 在这个简单的解决方案中,不需要解包格式化程序类(它基本上是一个带有
    \uuuuu missing\uuuu
    方法的dict)
  • 您可以将现有dict与Formatter类内联,这样您就不需要更改现有代码:
    Formatter(existing_dict)
    可以很好地工作
  • 如果您被迫使用双圆括号(
    {{some string}}
    )执行操作,则可以链接该方法。比如:


  • 如果在Python3.2下,那么我建议使用我第一次编写的答案,因为如果字符串中有一些参数,而dict中没有这些参数(这将导致
    KeyError
    ),它将查找并更新这些参数。如果您的dict超过了字符串所需的内容,那么您不需要做任何事情,
    str.format
    将完全忽略它,谢谢。我添加了更多的上下文。我也希望避免使用regexp,但鉴于我添加的上下文,我不确定这是否可行?谢谢。我添加了更多的上下文。我也希望避免使用regexp,但鉴于我添加的上下文,我不确定这是否可行?我可以发誓我留下了评论,但没有看到。再说一遍:谢谢-我也希望避免使用regexp,但不确定是否可以在这里使用
    s.format(*g)
    -我在最初的问题中扩展了上下文。如果您认为仍然可以避免使用regexp,我肯定会使用它!谢谢发布和更新!顺便说一句,我想你无意中回答了自己的回答:这很好。刚试过。python中有太多的内置功能正在等待被发现。我想知道我们是否可以做一些魔术,在字符串匹配中用{{}替换{}而不使用另一个模式替换?我正在使用一个模板,它恰好使用了{{param}而不是{param}。我明白了,看起来Angular很难强迫你,没关系,只需运行该方法两次。。。有点悲伤,但它起作用了。我会更新为完美的,像一个迷人的作品!我可以发誓我留下了评论,但没有看到。再说一遍:谢谢-我也希望避免使用regexp,但不确定是否可以在这里使用
    s.format(*g)
    -我在最初的问题中扩展了上下文。如果您认为仍然可以避免使用regexp,我肯定会使用它!谢谢发布和更新!顺便说一句,我想你无意中回答了自己的回答:这很好。刚试过。python中有太多的内置功能正在等待被发现。我想知道我们是否有可能这样做