Reputation: 9758
I want to write something like
format_specifier = "{some_dict[some_key]}"
to later use it together with .format()
:
result = format_specifier.format(some_dict={"one": "eins", "two": "zwei"}, some_key="one")
which I wanted to evaluate to "eins"
, but instead I get a KeyError
:
KeyError: 'some_key'
I also tried extra braces: "{some_dict[{some_key}]}"
resulting in KeyError: '{some_key}'
..
Is nesting format strings like this possible in the first place?
Note: I have to evaluate the string later so I guess f-string formatting is not an option for me..
Upvotes: 1
Views: 717
Reputation: 9758
Inspired by rioV8 I now do it like this, but I think it can be simplified very much if not Python has a built-in method to do this:
def formatComplex(specifier: str, format_data):
result = specifier
while True:
matches = re.findall(".*{([A-Za-z0-9_\-\/\ \,\.\'\"\(\)\[\]]+)}.*", result)
if not matches:
break
for m in matches:
result = result.replace("{%s}" % m, str(eval(m, None, format_data)))
return result
>>> format_specifier = "{some_dict[another_dict[some_key]]} world"
>>> formatComplex(format_specifier, {
... "some_dict": {3: "Hello"},
... "another_dict": "three": 3},
... "some_key":"three"})
Hello world
>>> formatComplex("Hello {who} {what} bar", {"who": "world", "what": "foo"})
Hello world foo bar
Upvotes: 0
Reputation: 28643
If you use eval
and define your used format arguments as a collection of local variables you can evaluate the format string.
format_specifier = "some_dict[another_dict[some_key]]"
def formatComplex(str, **kwargs):
# check str for correct format: only regex [a-zA-Z0-9\[\]] allowed
return eval(str, None, kwargs)
result = formatComplex(format_specifier, some_dict={3:"Hello"}, another_dict={"bla":3}, some_key="bla")
print (result)
You can add this to your string formatting by writing your own string.Formatter
sub class and implement a new parse()
method that substitutes these complex formats into literal text
Upvotes: 1