Comment puis-je échapper sélectivement le pourcentage (%) dans les chaînes Python?

364

J'ai le code suivant

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

print(selectiveEscape)

Je voudrais obtenir la sortie:

Print percent % in sentence and not have it break.

Que se passe-t-il réellement:

    selectiveEscape = "Use percent % in sentence and not %s" % test
TypeError: %d format: a number is required, not str
jondykeman
la source
57
Pourquoi pas \%? C'était ma supposition, je suis surpris de constater que c'est %%plutôt - semble assez contre-intuitif.
Demis
3
% isignifie "une représentation décimale d'un entier, complétée à gauche par des espaces.
Antti Haapala
3
L'évasion est à la fonction, pas à la syntaxe du langage. Par conséquent, si l'évasion se produisait, \%ce serait en réalité \\%lorsqu'elle était écrite en code ordinaire. <escape><escape>est le schéma typique que j'ai vu, et \se trouve être le personnage d'évasion le plus courant, pour le meilleur ou pour le pire.
shemnon du
1
@Demis et comment vous échapper \ si vous deviez imprimer \\%? Vous devrez obligatoirement échapper par la répétition de caractères spéciaux, si les caractères spéciaux ne sont pas non plus spéciaux selon les circonstances.
Sassa NF
2
Je pense qu'il est ennuyeux en Python que le% littéral soit encodé par "%%" et non par "\%".
MasterControlProgram

Réponses:

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
la source
38
En Python 3.3.5, print('%s%%' % 100)imprime 100%. Mais print('%%')imprime %%. Il semble donc que vous n'ayez pas à échapper aux signes% si vous n'effectuez pas de substitutions.
Zenadix
5
@Zenadix Cela est également vrai dans Python 2.7
Tom
2
Notez que la %méthode est en fait obsolète (en Python 3) en faveur de str.format(): docs.python.org/2/library/stdtypes.html#str.format
dantiston
8
Notez que la %méthode n'est pas dépréciée en Python 3.6. Il continuera à être pris en charge au lieu de sa similitude avec c, c ++, etc. str.format()et les chaînes f sont préférées mais non appliquées.
Aaron
Je viens de remarquer que si la chaîne est une chaîne json, la lecture d'un fichier n'a même pas besoin d'échapper au %signe. Tout %va faire
wander95
57

Alternativement, à partir de Python 2.6, vous pouvez utiliser un nouveau formatage de chaîne (décrit dans PEP 3101 ):

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

ce qui est particulièrement pratique car vos cordes se compliquent.

Karmel
la source
+1, alors que je pensais que op cherchait une réponse basée sur% que je préfère de loin utiliser de formatnos jours.
Nolen Royalty
2
Le seul problème avec cela est lorsque le texte que vous souhaitez formater est HTML avec une section de style CSS.
Broseph
Que recommandez-vous pour la mise en forme de texte HTML qui contient une section de style CSS, @Broseph?
DucRP
1
J'avais tort. Si vous utilisez des accolades doubles dans votre CSS, tout va bien.
Broseph
37

essayez d'utiliser %%pour imprimer le signe%.

openmeet123
la source
5

Vous ne pouvez pas vous échapper de manière sélective %, comme cela a %toujours une signification particulière en fonction du personnage suivant.

Dans la documentation de Python, au bas du deuxième tableau de cette section, il indique:

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

Par conséquent, vous devez utiliser:

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

(veuillez noter le changement explicite de tuple comme argument %)

Sans savoir ce qui précède, j'aurais fait:

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

avec les connaissances que vous aviez évidemment déjà.

Anthon
la source
3

Si le modèle de mise en forme a été lu à partir d'un fichier et que vous ne pouvez pas vous assurer que le contenu double le signe de pourcentage, vous devez probablement détecter le caractère de pourcentage et décider par programme s'il s'agit du début d'un espace réservé ou non. Ensuite, l'analyseur doit également reconnaître des séquences comme %d(et d'autres lettres qui peuvent être utilisées), mais aussi %(xxx)setc.

Un problème similaire peut être observé avec les nouveaux formats - le texte peut contenir des accolades.

pepr
la source
1

Si vous utilisez Python 3.6 ou une version plus récente, vous pouvez utiliser la chaîne 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.
Jaroslav Bezděk
la source
-3

J'ai essayé différentes méthodes pour imprimer un titre de sous-intrigue, regardez comment cela fonctionne. C'est différent quand j'utilise du latex.

Cela fonctionne avec '%%' et 'string' + '%' dans un cas typique.

Si vous utilisez Latex, cela a fonctionné en utilisant 'string' + '\%'

Donc, dans un cas typique:

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

Exemples de titres avec%

Si nous utilisons du latex:

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

Nous obtenons ceci: Exemple de titre avec% et latex

user245554
la source