Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if string has format arguments in Python?

I am formatting strings using named arguments with .format(). How can I obtain a list of arguments?

For example:

>>> my_string = 'I live in {city}, {state}, {country}.'
>>> get_format_args(my_string)
# ['city', 'state', 'country']

Note that order does not matter. I have dug a fair amount into the string.Formatter documentation to no avail. I am sure you could write regex to do this, but there must bet a more elegant way.

like image 757
Nolan Conaway Avatar asked Sep 11 '17 17:09

Nolan Conaway


People also ask

What does __ format __ do in Python?

The __format__ method is responsible for interpreting the format specifier, formatting the value, and returning the resulting string. It is safe to call this function with a value of “None” (because the “None” value in Python is an object and can have methods.)

What is %d and %i in Python?

The reason why there are two is that, %i is just an alternative to %d ,if you want to look at it at a high level (from python point of view). Here's what python.org has to say about %i: Signed integer decimal. And %d: Signed integer decimal. %d stands for decimal and %i for integer. but both are same, you can use both.

What is string formatting in Python?

String formatting is also known as String interpolation. It is the process of inserting a custom string or variable in predefined text. custom_string "String formatting" printf"custom_string is a powerful technique" Powered by Datacamp Workspace. String formatting is a powerful technique.

What is 5d in Python?

Output 12 1234 12.235 00012 0012.235. Here, in the first statement, {:5d} takes an integer argument and assigns a minimum width of 5. Since, no alignment is specified, it is aligned to the right.


2 Answers

It looks like you can get field names using the Formatter.parse method:

>>> import string
>>> my_string = 'I live in {city}, {state}, {country}.'
>>> [tup[1] for tup in string.Formatter().parse(my_string) if tup[1] is not None]
['city', 'state', 'country']

This will also return non-named arguments. Example: "{foo}{1}{}" will return ['foo', '1', '']. But if necessary you can filter out the latter two by using str.isdigit() and comparing against the empty string respectively.

like image 64
Kevin Avatar answered Oct 10 '22 01:10

Kevin


Regex can solve your problem.

>>> import re 
>>> re.findall(r'{(.*?)}', 'I live in {city}, {state}, {country}.')
['city', 'state', 'country']

Edit:

To avoid matching escaped placeholders like '{{city}}' you should change your pattern to something like:

(?<=(?<!\{)\{)[^{}]*(?=\}(?!\}))

Explanation:

(?<=      # Assert that the following can be matched before the current position
 (?<!\{)  #  (only if the preceding character isn't a {)
\{        #  a {
)         # End of lookbehind
[^{}]*    # Match any number of characters except braces
(?=       # Assert that it's possible to match...
 \}       #  a }
 (?!\})   #  (only if there is not another } that follows)
)         # End of lookahead
like image 30
Marco Avatar answered Oct 10 '22 02:10

Marco