alexandernst
alexandernst

Reputation: 15099

How to handle unbalanced brackets with string formatting

I have the following code that interpolates values in strings:

from collections import defaultdict
"This is {foo} {bar}".format_map(defaultdict(str, **{"foo": "a test"}))

>>> 'This is a test '

This interpolates known values and replaces unknown values with an empty string.

But if I write an unbalanced bracket in the string:

"This is {foo} {bar]".format_map(defaultdict(str, **{"foo": "a test"}))

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: expected '}' before end of string

Is there a way I can avoid this error and get the following output?

"This is {foo} {bar]".format_map(defaultdict(str, **{"foo": "a test"}))

>>> 'This is a test {bar]'

Upvotes: 4

Views: 331

Answers (2)

MisterMiyagi
MisterMiyagi

Reputation: 51999

Format strings, both for str.format and f-strings, begin a format field by {. This is not dependent on whether the field is ever closed.

Escape the brace as {{ to show that it is a literal brace, not the beginning of a format field.

>>> "This is {foo} {{bar]".format_map(defaultdict(str, **{"foo": "a test"}))
'This is a test {bar]'

Upvotes: 0

s3dev
s3dev

Reputation: 9711

This can be accomplished using the Template class of the built-in string library.

Official Python docs on the class.

Essentially, use a dollar sign before the variable which is to be replaced, as shown here. Then, call the substitute() function and pass in a dict with the replacement values.

from collections import defaultdict
from string import Template

s = Template("This is $foo {bar]")

s.substitute({'foo': 'a test'})
>>> 'This is a test {bar]'

Or, in your specific case using defaultdict:

s.substitute(defaultdict(str, **{'foo': 'a test'}))
>>> 'This is a test {bar]'

s.substitute(defaultdict(str, **{'BOB': 'a test'}))
>>> 'This is  {bar]'

Upvotes: 2

Related Questions