#python #python-3.x #string #format
#python #python-3.x #строка #форматирование
Вопрос:
У меня есть следующий код, который интерполирует значения в строках:
from collections import defaultdict
"This is {foo} {bar}".format_map(defaultdict(str, **{"foo": "a test"}))
>>> 'This is a test '
Это интерполирует известные значения и заменяет неизвестные значения пустой строкой.
Но если я напишу несбалансированную скобку в строке:
"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
Есть ли способ избежать этой ошибки и получить следующий вывод?
"This is {foo} {bar]".format_map(defaultdict(str, **{"foo": "a test"}))
>>> 'This is a test {bar]'
Комментарии:
1. Поймать ошибку?
2. @PDHide Конечно, я могу поймать ошибку, но что потом? Я все еще хочу получить частично интерполированную строку вместо полного отсутствия строки.
3. Взгляните на класс Template в
string
библиотеке. Все это встроено. Будет работать над ответом…4. @alexandernst разве вы не можете использовать регулярное выражение, чтобы найти допустимый формат и заменить его значением в словаре вместо использования format ?
5. docs.python.org/library/string.html#formatstrings Вы можете избежать фигурной скобки, используя двойную фигурную скобку
Ответ №1:
Это может быть достигнуто с помощью Template
класса встроенной string
библиотеки.
Официальные документы Python по классу.
По сути, используйте знак доллара перед переменной, которая должна быть заменена, как показано здесь . Затем вызовите substitute()
функцию и передайте a dict
с заменяющими значениями.
from collections import defaultdict
from string import Template
s = Template("This is $foo {bar]")
s.substitute({'foo': 'a test'})
>>> 'This is a test {bar]'
Или, в вашем конкретном случае, используя defaultdict
:
s.substitute(defaultdict(str, **{'foo': 'a test'}))
>>> 'This is a test {bar]'
s.substitute(defaultdict(str, **{'BOB': 'a test'}))
>>> 'This is {bar]'
Ответ №2:
Строки формата, как для str.format
, так и для f-строк, начинаются с поля формата {
. Это не зависит от того, закрыто ли поле когда-либо.
Экранируйте фигурную скобку, {{
чтобы показать, что это буквальная фигурная скобка, а не начало поля формата.
>>> "This is {foo} {{bar]".format_map(defaultdict(str, **{"foo": "a test"}))
'This is a test {bar]'
Комментарии:
1. Вопрос возникает из-за строки с ошибками (возможно, от конечного пользователя). Экранирование скобки в этой ситуации невозможно.
2. @alexandernst Тогда ни один из других ответов тоже не сработает. Принятый ответ также требует переписывания строки, например. Просто для ясности, вы ищете способ безопасного форматирования произвольных входных строк? Знают ли пользователи о том, что происходит форматирование строк, т. Е. Ожидают ли они, что поля формата и экранированные фигурные скобки будут соблюдены?
3. Я ищу способ интерполировать большую часть (если не все) произвольного пользовательского ввода. В случае, если что-то отсутствует / неправильно, я бы хотел просто пропустить этот бит и перейти к следующей части строки. Принятое решение будет делать именно это, в то время как ваше требует, чтобы пользователи знали о «экранировании».
4. @alexandernst Принятый ответ также требует, чтобы пользователи знали об экранировании. Например,
${foo]
это недопустимое поле шаблона, и его нужно будет экранировать как$${foo]
; аналогично,$$foo
это будет случайное экранирование, если вы не знаете об этом. Любой синтаксис встроенного формата имеет экранирование из-за замены действительного значения символа. Таким образом, мой вопрос, что вы на самом деле считаете жизнеспособным вводом.