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

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.

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.


+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


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à.


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.


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.

-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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.