Python 从模板中获取密钥

Python 从模板中获取密钥,python,string-formatting,Python,String Formatting,我想获得字符串模板在替换中可能使用的所有可能的关键字参数的列表 除了re之外,还有其他方法吗? 我想这样做: text="$one is a $lonely $number." keys = get_keys(text) # keys = ('one', 'lonely', 'number') 我正在编写一个简单的类似Mad lib的程序,我想用或来执行模板替换。我想写“故事”,让我的程序生成一个模板文件,其中包含用户需要生成的所有“关键词”(名词、动词等)。我知道我可以用正则表达式实现这一

我想获得字符串模板在替换中可能使用的所有可能的关键字参数的列表

除了re之外,还有其他方法吗?

我想这样做:

text="$one is a $lonely $number."
keys = get_keys(text) 
# keys = ('one', 'lonely', 'number')
我正在编写一个简单的类似Mad lib的程序,我想用或来执行模板替换。我想写“故事”,让我的程序生成一个模板文件,其中包含用户需要生成的所有“关键词”(名词、动词等)。我知道我可以用正则表达式实现这一点,但我想知道是否有其他解决方案?我对string.format和string模板的替代方案持开放态度

我原以为会有解决办法,但我没有在快速搜索中找到它。我确实找到了这个问题,但这不是我真正想要的。它只是重申,这可以通过
re
实现

编辑:

我应该注意,
$
是对“$”的转义,而不是我想要的标记<代码>$$5应渲染为“$5”。

尝试
str.strip()
以及
str.split()

你可以试试:

def get_keys(s):
    tokens = filter(lambda x: x[0] == "$", s.split())
    return map(lambda x: x[1:], tokens)

为什么要避免使用正则表达式?它们在这方面非常有效:

>>> re.findall(r'\$[a-z]+', "$one is a $lonely $number.")
['$one', '$lonely', '$number']

模板,签出,可以调用回调来做你想做的事情。

< P>如果使用<代码>字符串。格式< /C> >,考虑使用内置类<代码>字符串。格式化程序有<代码> PARSER()/<代码>方法:

>>> from string import Formatter
>>> [i[1] for i in Formatter().parse('Hello {1} {foo}')  if i[1] is not None]
['1', 'foo']

有关更多详细信息,请参阅。

您可以使用记录调用的插入指令的字典或defaultdict来呈现它一次,然后检查它所要求的内容

>>> import string
>>> get_keys = lambda s:[el.strip(string.punctuation) 
                         for el in s.split()if el.startswith('$')]
>>> get_keys("$one is a $lonely $number.")
['one', 'lonely', 'number']
from collections import defaultdict
d = defaultdict("bogus")
text%d
keys = d.keys()

string.Template
类具有用作属性的模式。您可以打印模式以获得匹配的组

>>> print string.Template.pattern.pattern

    \$(?:
      (?P<escaped>\$) |   # Escape sequence of two delimiters
      (?P<named>[_a-z][_a-z0-9]*)      |   # delimiter and a Python identifier
      {(?P<braced>[_a-z][_a-z0-9]*)}   |   # delimiter and a braced identifier
      (?P<invalid>)              # Other ill-formed delimiter exprs
    )
如上所示,如果使用大括号执行
${one}
,它将转到结果元组的第三位:

>>> string.Template.pattern.findall('${one} is a $lonely $number.')
[('', '', 'one', ''), ('', 'lonely', '', ''), ('', 'number', '', '')]
因此,如果您想获得所有钥匙,您必须执行以下操作:

>>> [s[1] or s[2] for s in string.Template.pattern.findall('${one} is a $lonely $number.$$') if s[1] or s[2]]
['one', 'lonely', 'number']

我不想避免使用正则表达式,我只是想知道是否还有其他方法。如果你想要一个脖子很长的非洲动物,当然可以拉伸一条鳄鱼,但在大多数情况下,与长颈鹿搭配更容易。$**是**字符串的一部分。标点符号**,这使得**lstrip(“$”)的冗余度与我想要的差不多。也许我的问题需要进一步研究,但我基本上不想重新发明轮子。谢谢。如果字符串以键开头,则此操作无效。用
{foo}test
@syntacticmarmalade在Python3.6上对我来说很好。如果您的意思是列表末尾有一个
None
,那是因为字符串没有以键结尾。您可以只筛选出
None
的实例。
>>> string.Template.pattern.findall('${one} is a $lonely $number.')
[('', '', 'one', ''), ('', 'lonely', '', ''), ('', 'number', '', '')]
>>> [s[1] or s[2] for s in string.Template.pattern.findall('${one} is a $lonely $number.$$') if s[1] or s[2]]
['one', 'lonely', 'number']