Related:
You use curly braces ( {•••}
) to denote parts of strings to be formatted. If you want to use literal curly brace characters so that they're ignored by .format()
, you use double curly braces ( {{•••}}
). MCVE:
string = "{format} {{This part won't be formatted. The final string will have literal curly braces here.}}"
print string.format(format='string')
If you have a chain of .format()
s, you double the number of braces for each time you use .format()
. The last one is surrounded by 4 braces and ends up with literal curly braces in the final output. MCVE:
string = "{format1} {{format2}} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
print string.format(format1='string1').format(format2='string2')
It's also possible to format another format string into a format string. The last one is surrounded by 4 braces and ends up with literal curly braces in the final output. MCVE:
string = "{format1} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
print string.format(format1='{format2}').format(format2='string')
The problem arises when you use a chain of .format()
s depending on conditions determined at runtime. If you want a set of the curly braces to be escaped as literal characters, how many do you use? MCVE:
string = "{} {{{{{{Here I don't know exactly how many curly braces to use because this string is formatted differently due to conditions that I have no control over.}}}}}}"
if fooCondition:
string = string.format('{} bar')
if barCondition:
string = string.format('{} baz')
if bazCondition:
string = string.format('{} buzz')
string = string.format('foo')
print string
The 1st part of the string has 4 possible outputs:
foo
foo bar
foo baz bar
foo buzz baz bar
The 2nd part of the string ends up with a different number of curly braces depending on how many conditions are True
. I want the 2nd part's curly braces to stay permanently escaped, like not "shed a layer" every time .format()
is called. I can solve the problem like this, MCVE:
string = "{} {{DRY - Don't repeat yourself!}}"
if fooCondition:
string = string.format('{} bar').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
if barCondition:
string = string.format('{} baz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
if bazCondition:
string = string.format('{} buzz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
string = string.format('foo')
print string
But that's duplicate code (bad practice).
The MCVEs aren't my real code. My real code runs on a Google App Engine web server. It's super long and complex. I'm working with HTML, CSS, and JavaScript in strings. I want to insert content into the HTML via .format()
without messing up the curly braces of CSS and JS. My current implementation is un-scalable and very error-prone. I have to manage up to 5 consecutive curly braces (like this: {{{{{•••}}}}}
) to pass through .format()
chains untouched. I need to periodically re-insert curly braces into strings that aren't formatted a fixed number of times. What's an elegant way to fix this spaghetti code?
How to PERMANENTLY escape curly braces in Python format string?