You need to double the {{ and }}:

>>> x = " {{ Hello }} {0} "
>>> print(x.format(42))
' { Hello } 42 '

Here's the relevant part of the Python documentation for format string syntax:

Format strings contain “replacement fields” surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a brace character in the literal text, it can be escaped by doubling: {{ and }}.

Answer from Greg Hewgill on Stack Overflow
🌐
Codecademy
codecademy.com › learn › dacp-python-fundamentals › modules › dscp-python-strings › cheatsheet
Python Fundamentals: Python Strings Cheatsheet | Codecademy
Python strings can be indexed using the same notation as lists, since strings are lists of characters. A single character can be accessed with bracket notation ([index]), or a substring can be accessed using slicing ([start:end]).
🌐
Manifoldapp
cuny.manifoldapp.org › read › how-to-code-in-python-3 › section › 07f9968a-8f75-4d3c-8573-2e9282745e9e
How To Use String Formatters | How To Code in Python 3 | Manifold @CUNY
In this second example, we concatenated the string "open source" with the larger string, replacing the curly braces in the original string. Formatters in Python allow you to use curly braces as placeholders for values that you’ll pass through with the str.format() method.
🌐
Runestone Academy
runestone.academy › ns › books › published › fopp › Sequences › IndexOperatorWorkingwiththeCharactersofaString.html
6.3. Index Operator: Working with the Characters of a String — Foundations of Python Programming
The indexing operator (Python uses square brackets to enclose the index) selects a single character from a string. The characters are accessed by their position or index value.
🌐
Edlitera
edlitera.com › blog › posts › python-parentheses
Python Parentheses Cheat Sheet | Edlitera
That’s why it's important to understand what each type of parentheses in Python represents and how to use each type of parentheses correctly in your Python code. In this article, I'll cover what standard parentheses, square brackets, and curly braces represent to Python when it interprets the code you've written.
🌐
AskPython
askpython.com › home › how to print brackets in python?
How to Print Brackets in Python? - AskPython
May 30, 2023 - Here, we used an empty string variable to print the brackets. We concatenated the bracket with the empty string and printed it.
🌐
Data Science Discovery
discovery.cs.illinois.edu › guides › Python-Fundamentals › brackets
Parentheses, Square Brackets and Curly Braces in Python - Data Science Discovery
March 22, 2024 - Brief description on when to use parentheses `()`, square brackets `[]` and curly braces `{}` in python
Find elsewhere
🌐
Processing
py.processing.org › reference › indexbrackets.html
[] (Index brackets) \ Language (API)
Python Mode for Processing extends the Processing Development Environment with the Python programming language.
Top answer
1 of 2
5
>>> import re
>>> oldString = "this is my {{string-d}}"
>>> oldString2 = "this is my second{{ new_string-d }}"
>>> re.sub(r"(\w*-d)", r"(\1)", oldString)
'this is my {{(string-d)}}'
>>> re.sub(r"(\w*-d)", r"(\1)", oldString2)
'this is my second{{ (new_string-d) }}'

Note that this matches "words" assuming that a word is composed of only letters, numbers, and underscores.


Here's a more thorough breakdown of what's happening:

  • An r before a string literal means the string is a "raw string". It prevents Python from interpreting characters as an escape sequence. For instance, r"\n" is a slash followed by the letter n, rather than being interpreted as a single newline character. I like to use raw strings for my regex patterns, even though it's not always necessary.
  • the parentheses surrounding \w*-d is a capturing group. It indicates to the regex engine that the contents of the group should be saved for later use.
  • the sequence \w means "any alphanumeric character or underscore".
  • * means "zero or more of the preceding item". \w* together means "zero or more alphanumeric characters or underscores".
  • -d means "a hyphen followed by the letter d.

All together, (\w*-d) means "zero or more alphanumeric characters or underscores, followed by a hyphen and the letter d. Save all of these characters for later use."

The second string describes what the matched data should be replaced with. "\1" means "the contents of the first captured group". The parentheses are just regular parentheses. All together, (\1) in this context means "take the saved content from the captured group, surround it in parentheses, and put it back into the string".


If you want to match more characters than just alphanumeric and underscore, you can replace \w with whatever collection of characters you want to match.

>>> re.sub(r"([\w\.\[\]]*-d)", r"(\1)", "{{startingHere[zero1].my_string-d }}")
'{{(startingHere[zero1].my_string-d) }}'

If you also want to match words ending with "-d()", you can match a parentheses pair with \(\) and mark it as optional using ?.

>>> re.sub(r"([\w\.\[\]]*-d(\(\))?)", r"(\1)", "{{startingHere[zero1].my_string-d() }}")
'{{(startingHere[zero1].my_string-d()) }}'
2 of 2
0

If you want the bracketing to only take place inside double curly braces, you need something like this:

re.sub(r'({{\s*)([^}]*-d)(\s*}})', r'\1(\2)\3', s)

Breaking that down a bit:

# the target pattern
r'({{\s*)([^}]*-d)(\s*}})'
# ^^^^^^^ capture group 1, opening {{ plus optional space
#        ^^^^^^^^^ capture group 2, non-braces plus -d
#                 ^^^^^^^ capture 3, spaces plus closing }}

The replacement r'\1(\2)\3' just assembles the groups, with parenthesis around the middle one.

Putting it together:

import re

def quote_string_d(s):
    return re.sub(r'({{\s*)([^}]*-d)(\s*}})', r'\1(\2)\3', s)

print(quote_string_d("this is my {{string-d}}"))
print(quote_string_d("this is my second{{ new_string-d }}"))
print(quote_string_d("this should not be quoted other_string-d "))

Output:

this is my {{(string-d)}}
this is my second{{ (new_string-d) }}
this should not be quoted other_string-d 

Note the third instance does not get the parentheses, because it's not inside {{ }}.

🌐
GeeksforGeeks
geeksforgeeks.org › python › parentheses-square-brackets-and-curly-braces-in-python
Parentheses, Square Brackets and Curly Braces in Python - GeeksforGeeks
July 26, 2025 - For example, my_list[0] or my_string[1:4] . ... In conclusion, understanding the differences between parentheses (), curly braces {}, and square brackets [] in Python is essential for writing clear, efficient, and well-structured code. Parentheses are versatile, used for function calls, defining tuples, and grouping expressions.
🌐
SheCanCode
shecancode.io › home › news & articles › string formatting in python
String Formatting in Python - SheCanCode
December 11, 2023 - We can mention the format specifier inside the curly brackets. It allows us to control the formatting of the values. Like if we mention {:,.2f} →It indicates two decimal places. The values will be rounded to two decimal places. When we use f string formatting, we have to include ‘f’ before the opening quotation mark.
🌐
EnableGeek
enablegeek.com › home › print your (box,curly, parentheses) brackets in python
Print Your (Box,Curly, Parentheses) Brackets in Python - EnableGeek
March 21, 2024 - In Python, you can include box brackets (also known as square brackets) in a string by simply enclosing them within the string.
🌐
Django CAS
djangocas.dev › blog › python › python-literal-curly-braces-in-f-string
Python: How to print literal curly brace { or } in f-string and format string
July 10, 2024 - The parts of the string outside curly braces are treated literally, except that any doubled curly braces '{{' or '}}' are replaced with the corresponding single curly brace. A single opening curly bracket '{' marks a replacement field, which starts with a Python expression.
🌐
Python
docs.python.org › 3.3 › library › string.html
6.1. string — Common string operations — Python 3.3.7 documentation
March 9, 2022 - It is exposed as a separate function for cases where you want to pass in a predefined dictionary of arguments, rather than unpacking and repacking the dictionary as individual arguments using the *args and **kwargs syntax. vformat() does the work of breaking up the format string into character data and replacement fields.
🌐
Reuven Lerner
lerner.co.il › home › blog › python › python parentheses primer
Python parentheses primer — Reuven Lerner
November 10, 2022 - The fact that square brackets are so generalized in this way means that Python can take advantage of them, even on user-created objects. You might also be familiar with slices. Slices are similar to individual indexes, except that they describe a range of indexes. For example: In [46]: import string In [47]: string.ascii_lowercase[10:20] Out[47]: 'klmnopqrst' In [48]: string.ascii_lowercase[10:20:3] Out[48]: 'knqt'
🌐
w3resource
w3resource.com › python-exercises › class-exercises › python-class-exercise-3.php
Python: Validity of a string of parentheses - w3resource
Write a Python class to check the validity of a string of parentheses, '(', ')', '{', '}', '[' and ']. These brackets must be closed in the correct order, for example "()" and "()[]{}" are valid but "[)", "({[)]" and "{{{" are invalid.
🌐
LaunchCode
education.launchcode.org › lchs › chapters › strings › bracket-notation.html
7.2. Bracket Notation — LaunchCode's LCHS documentation
Index values are integers representing the position of a character within a given string. ... Note that this is another example of zero-based indexing. The count begins with the value 0. Bracket notation is the special syntax that allows us to access the single characters that make up a string.