Как я могу выборочно экранировать проценты (%) в строках Python?

364

У меня есть следующий код

test = "have it break."
selectiveEscape = "Print percent % in sentence and not %s" % test

print(selectiveEscape)

Я хотел бы получить вывод:

Print percent % in sentence and not have it break.

Что на самом деле происходит:

    selectiveEscape = "Use percent % in sentence and not %s" % test
TypeError: %d format: a number is required, not str
jondykeman
источник
57
Почему не так \%? Это было мое предположение, я удивлен, обнаружив, что %%вместо этого - кажется довольно нелогичным.
Демис
3
% iозначает «десятичное представление целого числа, дополненное слева пробелами.
Антти Хаапала
3
Экранирование - это функция, а не синтаксис языка. Следовательно, если побег был, \%это было бы на самом деле, \\%когда написано в обычном коде. <escape><escape>это типичный образец, который я видел, и, как ни \крути, это самый распространенный побег.
Шемнон
1
@ Демис, и как ты убегаешь, \ если тебе пришлось печатать \\%? Вы обязаны требовать экранирования через повторение специальных символов, если специальные символы также не являются специальными в зависимости от обстоятельств.
Сасса Н.Ф.
2
Я думаю, что это раздражает в Python, что буквальный% кодируется "%%", а не "\%".
MasterControlProgram

Ответы:

625
>>> test = "have it break."
>>> selectiveEscape = "Print percent %% in sentence and not %s" % test
>>> print selectiveEscape
Print percent % in sentence and not have it break.
Нолен Роял
источник
38
В Python 3.3.5 print('%s%%' % 100)печатает 100%. Но print('%%')печатает %%. Похоже, вам не нужно избегать знаков%, если вы не делаете замены.
Zenadix
5
@Zenadix Это верно и для Python 2.7
Том
2
Обратите внимание, что %метод на самом деле не рекомендуется (в Python 3) в пользу str.format(): docs.python.org/2/library/stdtypes.html#str.format
dantiston
8
Обратите внимание, что этот %метод не рекомендуется в Python 3.6. Он будет по-прежнему поддерживаться вместо его сходства с c, c ++ и т. Д., str.format()И f-строки предпочтительнее, но не применяются.
Аарон
Просто заметил, что если строка является строкой json, при чтении из файла вам даже не нужно экранировать %знак. Просто %сделаю
wander95
57

В качестве альтернативы, начиная с Python 2.6, вы можете использовать новое форматирование строки (описано в PEP 3101 ):

'Print percent % in sentence and not {0}'.format(test)

что особенно удобно, поскольку ваши струны становятся более сложными.

Кармель
источник
+1, хотя я полагал, что op ищет основанный на% ответ, который я предпочитаю использовать в formatэти дни.
Нолен Роялти
2
Единственная проблема с этим, когда текст, который вы хотите отформатировать, это HTML с разделом стиля CSS.
Broseph
Что вы рекомендуете для форматирования текста HTML, который содержит раздел стиля CSS, @Broseph?
DucRP
1
Я был неправ. Если вы используете двойные скобки в вашем CSS, у вас все хорошо.
Бросеф
37

попробуйте использовать %%для печати знака%.

openmeet123
источник
5

Вы не можете выборочно убежать %, так как %всегда имеет особое значение в зависимости от следующего символа.

В документации Python, в нижней части второй таблицы в этом разделе, говорится:

'%'        No argument is converted, results in a '%' character in the result.

Поэтому вы должны использовать:

selectiveEscape = "Print percent %% in sentence and not %s" % (test, )

(обратите внимание на точное изменение кортежа в качестве аргумента %)

Не зная о вышесказанном, я бы сделал:

selectiveEscape = "Print percent %s in sentence and not %s" % ('%', test)

со знанием, которое вы, очевидно, уже имели.

Энтон
источник
3

Если шаблон форматирования был прочитан из файла, и вы не можете гарантировать, что содержимое удваивает знак процента, то вам, вероятно, придется определить символ процента и программно решить, является ли он заполнителем или нет. Затем синтаксический анализатор должен также распознавать последовательности, подобные %d(и другим буквам, которые могут использоваться), но также %(xxx)sи т. Д.

Аналогичная проблема наблюдается с новыми форматами - текст может содержать фигурные скобки.

pepr
источник
1

Если вы используете Python 3.6 или новее, вы можете использовать f-строку :

>>> test = "have it break."
>>> selectiveEscape = f"Print percent % in sentence and not {test}"
>>> print(selectiveEscape)
... Print percent % in sentence and not have it break.
Ярослав Бездек
источник
-3

Я пробовал разные способы напечатать заголовок подзаговора, посмотрите, как они работают. Другое дело, когда я использую латекс.

Он работает с '%%' и 'string' + '%' в типичном случае.

Если вы используете латекс, он работал, используя 'string' + '\%'

Итак, в типичном случае:

import matplotlib.pyplot as plt
fig,ax = plt.subplots(4,1)
float_number = 4.17
ax[0].set_title('Total: (%1.2f' %float_number + '\%)')
ax[1].set_title('Total: (%1.2f%%)' %float_number)
ax[2].set_title('Total: (%1.2f' %float_number + '%%)')
ax[3].set_title('Total: (%1.2f' %float_number + '%)')

Примеры заголовков с%

Если мы используем латекс:

import matplotlib.pyplot as plt
import matplotlib
font = {'family' : 'normal',
        'weight' : 'bold',
        'size'   : 12}
matplotlib.rc('font', **font)
matplotlib.rcParams['text.usetex'] = True
matplotlib.rcParams['text.latex.unicode'] = True
fig,ax = plt.subplots(4,1)
float_number = 4.17
#ax[0].set_title('Total: (%1.2f\%)' %float_number) This makes python crash
ax[1].set_title('Total: (%1.2f%%)' %float_number)
ax[2].set_title('Total: (%1.2f' %float_number + '%%)')
ax[3].set_title('Total: (%1.2f' %float_number + '\%)')

Мы получаем это: Пример заголовка с% и латексом

user245554
источник