Jak mogę selektywnie uciec procent (%) w ciągach Python?


364

Mam następujący kod

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

print(selectiveEscape)

Chciałbym uzyskać wynik:

Print percent % in sentence and not have it break.

Co się właściwie dzieje:

    selectiveEscape = "Use percent % in sentence and not %s" % test
TypeError: %d format: a number is required, not str

57
Dlaczego nie jest to \%? Tak sądziłem, jestem zaskoczony, że to %%zamiast tego - wydaje się dość sprzeczne z intuicją.
Demis

3
% ioznacza „dziesiętną reprezentację liczby całkowitej, wypełnioną lewą spacją.
Antti Haapala

3
Wyjściem jest funkcja, a nie składnia języka. Stąd, jeśli ucieczką \%byłoby, to tak naprawdę byłoby, \\%gdyby napisano zwykłym kodem. <escape><escape>to typowy wzorzec, który widziałem, i \zdarza się, że jest najczęstszą postacią ucieczki, na dobre lub złe.
shemnon

1
@Demis i jak możesz uciec \ , gdybyś musiał wydrukować \\%? Jesteś zobowiązany do ucieczki poprzez powtarzanie znaków specjalnych, jeśli znaki specjalne również nie są specjalne w zależności od okoliczności.
Sassa NF,

2
Myślę, że denerwujące jest w Pythonie, że dosłowny% jest kodowany przez „%%”, a nie przez „\%”.
MasterControlProgram

Odpowiedzi:


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
W Python 3.3.5 print('%s%%' % 100)drukuje 100%. Ale print('%%')drukuje %%. Wygląda więc na to, że nie musisz uciekać od znaków%, jeśli nie dokonasz zamiany.
Zenadix,

5
@Zenadix Dotyczy to również Python 2.7
Tom

2
Zauważ, że %metoda jest faktycznie przestarzała (w Pythonie 3) na korzyść str.format(): docs.python.org/2/library/stdtypes.html#str.format
dantiston

8
Zauważ, że %metoda nie jest amortyzowana w Pythonie 3.6. Będzie nadal obsługiwany zamiast podobieństwa do c, c ++ itp., str.format()A ciągi f są preferowane, ale nie są egzekwowane.
Aaron,

Zauważyłem tylko, że jeśli ciąg jest ciągiem json, po odczytaniu z pliku nie musisz nawet uciekać od %znaku. Po prostu %zrobię
wander95,

57

Alternatywnie, począwszy od Pythona 2.6, możesz użyć nowego formatowania łańcucha (opisanego w PEP 3101 ):

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

co jest szczególnie przydatne, gdy twoje łańcuchy stają się bardziej skomplikowane.


+1, podczas gdy pomyślałem, że op szuka odpowiedzi opartej na%, o wiele wolę teraz używać format.
Nolen Royalty

2
Jedynym problemem jest to, że tekst, który chcesz sformatować, to HTML z sekcją stylu CSS.
Broseph

Co polecasz do formatowania tekstu HTML zawierającego sekcję stylu CSS, @Broseph?
DucRP,

1
Myliłem się. Jeśli używasz podwójnych nawiasów klamrowych w swoim CSS, nic ci nie jest.
Broseph


5

Nie możesz selektywnie uciec %, jak% zawsze ma specjalne znaczenie w zależności od następującej postaci.

W dokumentacji Pythona, na dole drugiej tabeli w tej sekcji, stwierdza:

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

Dlatego powinieneś użyć:

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

(zwróć uwagę na zmianę wydatków na krotkę jako argument na % )

Nie wiedząc o tym, zrobiłbym:

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

z wiedzą, którą oczywiście już posiadałeś.


3

Jeśli szablon formatowania został odczytany z pliku i nie możesz upewnić się, że treść podwaja znak procentu, prawdopodobnie musisz wykryć znak procentu i programowo zdecydować, czy jest to początek symbolu zastępczego, czy nie. Następnie analizator składni powinien rozpoznać sekwencje takie jak %d(i inne litery, których można użyć), ale także %(xxx)sitp.

Podobny problem można zaobserwować w nowych formatach - tekst może zawierać nawiasy klamrowe.


1

Jeśli używasz języka Python 3.6 lub nowszego, możesz użyć ciągu 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

Próbowałem różnych metod, aby wydrukować tytuł podploty, zobacz jak działają. Jest inaczej, gdy używam lateksu.

Działa z „%%” i „string” + „%” w typowym przypadku.

Jeśli używasz lateksu, działało to przy użyciu „string” + „\%”

W typowym przypadku:

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

Przykłady tytułów z%

Jeśli używamy lateksu:

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

Otrzymujemy to: przykładowy tytuł z% i lateksem

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.