String formatting with the format string syntax

Peter Otten __peter__ at web.de
Wed Sep 15 04:00:45 EDT 2010


Peter Otten wrote:

> Andre Alexander Bell wrote:
> 
>> On 09/14/2010 08:20 PM, Miki wrote:
>>> You can use ** syntax:
>>>>>> english = {'hello':'hello'}
>>>>>> s.format(**english)
>> 
>> Thanks for your answer. Actually your answer tells me that my example
>> was misleading. Consider the template
>> 
>> s = 'A template with {variable1} and {variable2} placeholders.'
>> 
>> I'm seeking a way to extract the named placesholders, i.e. the names
>> 'variable1' and 'variable2' from the template. I'm not trying to put in
>> values for them.
>> 
>> I hope this is clearer.
> 
>>>> s = 'A template with {variable1} and {variable2} placeholders.'
>>>> [name for _, name, _, _ in s._formatter_parser() if name is not None]
> ['variable1', 'variable2']

Caveat: the format spec may contain names, too. 
Here's an attempt to take that into account:

def extract_names(t, recurse=1):
    for _, name, fmt, _ in t._formatter_parser():
        if name is not None:
            yield name
        if recurse and fmt is not None:
            for name in extract_names(fmt, recurse-1):
                yield name

t = "before {one:{two}{three}} after"
print(t)

for name in extract_names(t):
    print(name)

>>> list(extract_names("{one:{two}{three}}"))
['one', 'two', 'three']

Don't expect correct results for illegal formats:
>>> list(extract_names("{one:{two:{three}}}"))
['one', 'two']
>>> "{one:{two:{three}}}".format(one=1, two=2, three=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Max string recursion exceeded

Duplicate names may occur:
>>> list(extract_names("{one} {one} {one}"))
['one', 'one', 'one']

Positional arguments are treated like names:
>>> list(extract_names("{0} {1} {0}"))
['0', '1', '0']
>>> list(extract_names("{} {} {}"))
['', '', '']

Peter



More information about the Python-list mailing list