¿Cómo puedo escapar selectivamente del porcentaje (%) en cadenas de Python?

364

Tengo el siguiente código

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

print(selectiveEscape)

Me gustaría obtener el resultado:

Print percent % in sentence and not have it break.

Lo que realmente sucede:

    selectiveEscape = "Use percent % in sentence and not %s" % test
TypeError: %d format: a number is required, not str
jondykeman
fuente
57
¿Por qué no lo es \%? Esa fue mi suposición, me sorprende descubrir que, en %%cambio, parece bastante contradictorio.
Demis
3
% isignifica "una representación decimal de un número entero, rellenado a la izquierda con espacios."
Antti Haapala
3
El escape es a la función, no a la sintaxis del lenguaje. Por lo tanto, si la fuga fue \%en realidad sería \\%cuando se escribe en código ordinario. <escape><escape>es el patrón típico que he visto, y \resulta ser el personaje de escape más común, para bien o para mal.
shemnon
1
@Demis y ¿cómo escapas \ si tuvieras que imprimir \\%? Es probable que deba escapar mediante la repetición de caracteres especiales, si los caracteres especiales tampoco son especiales dependiendo de las circunstancias.
Sassa NF
2
Creo que es molesto en Python que el% literal esté codificado por "%%" y no por "\%".
MasterControlProgram

Respuestas:

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.
Nolen Royalty
fuente
38
En Python 3.3.5, print('%s%%' % 100)impresiones 100%. Pero print('%%')huellas %%. Por lo tanto, parece que no tiene que escapar de los signos% si no realiza sustituciones.
Zenadix
55
@Zenadix Esto también es cierto en Python 2.7
Tom
2
Tenga en cuenta que el %método en realidad está en desuso (en Python 3) a favor de str.format(): docs.python.org/2/library/stdtypes.html#str.format
dantiston
8
Tenga en cuenta que el %método no se deprecia en Python 3.6. Continuará siendo compatible en lugar de su similitud con c, c ++, etc. str.format()y se prefieren las cadenas f pero no se aplican.
Aaron
Acabo de notar que si la cadena es una cadena json, al leerla desde un archivo, ni siquiera necesita escapar del %signo. Simplemente %lo haré
wander95
57

Alternativamente, a partir de Python 2.6, puede usar un nuevo formato de cadena (descrito en PEP 3101 ):

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

lo cual es especialmente útil a medida que sus cuerdas se vuelven más complicadas.

Karmel
fuente
+1, mientras pensaba que op estaba buscando una respuesta basada en%, prefiero usar formatestos días.
Nolen Royalty
2
El único problema con esto es cuando el texto que desea formatear es HTML con una sección de estilo CSS.
Broseph
¿Qué recomienda para el formato de texto HTML que contiene una sección de estilo CSS, @Broseph?
DucRP
1
Estaba equivocado. Si usa llaves dobles en su CSS, está bien.
Broseph
37

intente usar %%para imprimir el signo%.

openmeet123
fuente
5

No puedes escapar selectivamente %, ya que %siempre tiene un significado especial dependiendo del siguiente personaje.

En la documentación de Python, en el bottem de la segunda tabla en esa sección, dice:

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

Por lo tanto, debe usar:

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

(tenga en cuenta el cambio explícito a tupla como argumento para %)

Sin saber lo anterior, habría hecho:

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

con el conocimiento que obviamente ya tenías.

Anthon
fuente
3

Si la plantilla de formato se leyó de un archivo y no puede garantizar que el contenido duplique el signo de porcentaje, entonces probablemente tenga que detectar el carácter de porcentaje y decidir mediante programación si es el inicio de un marcador de posición o no. Entonces el analizador también debe reconocer secuencias como %d(y otras letras que se pueden usar), pero también %(xxx)setc.

Se puede observar un problema similar con los nuevos formatos: el texto puede contener llaves.

pepr
fuente
1

Si está utilizando Python 3.6 o posterior, puede usar f-string :

>>> test = "have it break."
>>> selectiveEscape = f"Print percent % in sentence and not {test}"
>>> print(selectiveEscape)
... Print percent % in sentence and not have it break.
Jaroslav Bezděk
fuente
-3

He intentado diferentes métodos para imprimir un título de subtrama, mira cómo funcionan. Es diferente cuando uso Latex.

Funciona con '%%' y 'string' + '%' en un caso típico.

Si usa Latex, funcionó usando 'string' + '\%'

Entonces, en un caso típico:

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 + '%)')

Ejemplos de títulos con%

Si usamos látex:

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 + '\%)')

Obtenemos esto: Ejemplo de título con% y latex

usuario245554
fuente