I would like to get a list of all possible keyword arguments a string template might use in a substitution.
Is there a way to do this other than re?
The string.Template class has the pattern that is uses as an attribute. You can print the pattern to get the matching groups
>>> print string.Template.pattern.pattern
\$(?:
(?P\$) | # Escape sequence of two delimiters
(?P[_a-z][_a-z0-9]*) | # delimiter and a Python identifier
{(?P[_a-z][_a-z0-9]*)} | # delimiter and a braced identifier
(?P) # Other ill-formed delimiter exprs
)
And for your example,
>>> string.Template.pattern.findall("$one is a $lonely $number.")
[('', 'one', '', ''), ('', 'lonely', '', ''), ('', 'number', '', '')]
As you can see above, if you do ${one} with braces it will go to the third place of the resulting tuple:
>>> string.Template.pattern.findall('${one} is a $lonely $number.')
[('', '', 'one', ''), ('', 'lonely', '', ''), ('', 'number', '', '')]
So if you want to get all the keys, you'll have to do something like:
>>> [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']