我想知道从字符串中枚举占位符的最佳方法是什么,我已经看到已经有另一篇文章询问how-can-i-find-all-placeholders-for-str-format-in-a-python-string-using-a-regex但是我不确定提供的答案是否正确地给了我什么我正在寻找,让我们来看看这个小小的测试:
import string
tests = [
['this is my placeholder 1 {} and this is the 2 {}', 2],
['another placeholder here {} and here \"{}\"', 2]
]
for s in tests:
num_placeholders = len([
name for text, name, spec, conv in string.Formatter().parse(s[0])])
if num_placeholders != s[1]:
print("FAIL: {0} has {1} placeholders!!! excepted result {2}".format(
s[0], num_placeholders, s[1]))
似乎string.Formatter没有给我正在寻找的预期答案:
FAIL: another placeholder here {} and here "{}" has 3 placeholders!!! excepted result 2
答案 0 :(得分:2)
因为你忽略了parse(s)
返回的元组上的其他元素:
>>> import string
>>>
>>> tests = [
... "{} spam eggs {}",
... "{0} spam eggs {1}",
... "{0:0.2f} spam eggs {1:0.2f}",
... ">>> list(string.Formatter().parse('{}'))
[('', '', '', None)]
spam eggs {{2}}"
... ]
>>> for s in tests:
... print [x for x in string.Formatter().parse(s)]
...
[('', '', '', None), (' spam eggs ', '', '', None)]
[('', '0', '', None), (' spam eggs ', '1', '', None)]
[('', '0', '0.2f', None), (' spam eggs ', '1', '0.2f', None)]
[('{', None, None, None), ('1}', None, None, None), (' spam eggs {', None, None, None), ('2}', None, None, None)]
编辑:我明白你的意思了。是的,解析的解释不直观也不明显。返回列表的长度不是占位符的数量,而是字符串的文字部分的计数,包括开头的空字符串,但不包括结尾的空字符串。每个元素还包含以下格式。例如:
>>> list(string.Formatter().parse('a {}'))
[('a ', '', '', None)]
这是基本情况,并且只有一个空字符串的文字文本。实际上有两个空字符串,但解析器不包含最后一个空字符串。
>>> list(string.Formatter().parse('{} b'))
[('', '', '', None), (' b', None, None, None)]
现在我们和以前一样:只有一个文字字符串" a"没有任何内容。由于格式括号后面没有任何内容,因此没有元素。
>>> list(string.Formatter().parse('a {1} b {2} c'))
[('a ', '1', '', None), (' b ', '2', '', None), (' c', None, None, None)]
这是一个有趣的案例:因为格式括号位于开头,所以第一个文字字符串是一个空的文字字符串,并且跟在字符串" B&#34 ;.
['a ', ' b ', ' c']
这是一个非常完整的例子。我们有三个文字字符串:>>> [x[0] for x in string.Formatter().parse('another placeholder here {} and here \"{}\"')]
['another placeholder here ', ' and here "', '"']
。令人困惑的部分是格式括号{}的特定格式信息与前一个文字字符串元素合并。
EDIT2:
>>> [x[0] for x in string.Formatter().parse('another placeholder here {} and here qqq{}www')]
['another placeholder here ', ' and here qqq', 'www']
我们遵循相同的逻辑。引号只是原始的文字字符串,我们可以将引号更改为其他内容:
>>> [x for x in string.Formatter().parse('a{}')]
[('a', '', '', None)]
>>> [x for x in string.Formatter().parse('a')]
[('a', None, None, None)]
如果您只考虑'名称'从每个返回的元组,你只得到文字字符串。在每个单独的元素之间是格式占位符。
您需要从格式化字符串的角度理解parse()的结果。此结果使得生成输出格式化字符串变得简单。例如:
>>> def count_placeholders(fmt):
... count = 0
... L = string.Formatter().parse(fmt)
... for x in L:
... if x[1] is not None:
... count += 1
... return count
...
>>> count_placeholders('')
0
>>> count_placeholders('{}')
1
>>> count_placeholders('{}{}')
2
>>> count_placeholders('a {}{}')
2
>>> count_placeholders('a {} b {}')
2
>>> count_placeholders('a {} b {} c')
2
使用此逻辑,您可以计算格式字符串中占位符的数量,如下所示:
echo
答案 1 :(得分:0)
import string
def count_placeholders(fmt):
return sum(1 for x in string.Formatter().parse(fmt) if x[1] is not None)