如何使用正则表达式在Python字符串中查找所有的str.format占位符?

11

我正在创建一个类,用于使用用户指定的格式重命名文件。该格式将是一个简单的字符串,其str.format方法将被调用以填充空白部分。

事实证明,我的过程需要提取包含在大括号内的变量名称。例如,一个字符串可能包含{user},它应该产生user。当然,在单个字符串中会有几组大括号,我需要按照出现顺序获取每个大括号内的内容,并将它们输出到列表中。

因此,"{foo}{bar}"应该产生['foo', 'bar']

我怀疑最容易的方法是使用re.split,但我对正则表达式一无所知。能否有人帮帮我?

提前感谢!


如果您事先知道所有可能的变量,只需将它们全部传递给 str.format - 它将忽略模式中不存在的变量。'{user}_{bar}'.format(user='Mike', foo=1, bar=2) 将输出 Mike_2。我碰巧已经将允许的变量固定在字典中,因此可以跳过在模式中查找变量的步骤。无论如何,了解 string.Formatter() 非常有用。 - yentsun
2个回答

63

另一种可能是使用Python的实际Formatter本身来为您提取字段名称:

>>> import string
>>> s = "{foo} spam eggs {bar}"
>>> string.Formatter().parse(s)
<formatteriterator object at 0x101d17b98>
>>> list(string.Formatter().parse(s))
[('', 'foo', '', None), (' spam eggs ', 'bar', '', None)]
>>> field_names = [name for text, name, spec, conv in string.Formatter().parse(s)]
>>> field_names
['foo', 'bar']

或(更短但信息量较少):

>>> field_names = [v[1] for v in string.Formatter().parse(s)]
>>> field_names
['foo', 'bar']

哦哦哦...我喜欢这个!我可能会接受Ashwini Chaudhary的答案,因为我特别要求一个正则表达式的解决方案,但我认为我会使用你的,因为我更好地理解它!谢谢! - Louis Thibault
2
这个能修改一下来查找 %(name)s 占位符吗? - TheDarkLord
1
在我看来,这是正确的答案。它使用与.format()相同的机制。 - Gustavo Gonçalves

18

使用 re.findall() 方法:

In [5]: import re

In [8]: strs = "{foo} spam eggs {bar}"

In [9]: re.findall(r"{(\w+)}", strs)
Out[9]: ['foo', 'bar']

只是一个快速的问题。re.findall 的结果是否保证按照它们在字符串中出现的顺序列出? - Louis Thibault
2
@blz 是的,因为字符串是从左到右解析的。 - Ashwini Chaudhary
注意,这不包括格式说明符,如{spam:3f}。@DSM的答案应该被接受。将\w修改为包括更多字符,直到它与str.format的完整规范匹配可能有效,但使用格式化程序本身更好(并且不容易在语法发生变化时出现故障)。 - ewen-lbh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接