unicode_escape
genel olarak çalışmıyor
string_escape
Veya unicode_escape
çözümün genel olarak çalışmadığı ortaya çıktı - özellikle gerçek Unicode varlığında çalışmıyor.
ASCII olmayan tüm karakterlerin kaçılacağından emin olabilirseniz (ve ilk 128 karakterin dışındaki hiçbir şeyin ASCII olmadığını unutmayın), unicode_escape
sizin için doğru olanı yapacaktır. Ancak dizenizde zaten ASCII olmayan herhangi bir gerçek karakter varsa, işler ters gidecektir.
unicode_escape
temelde baytları Unicode metne dönüştürmek için tasarlanmıştır. Ancak birçok yerde - örneğin, Python kaynak kodu - kaynak veriler zaten Unicode metindir.
Bunun doğru çalışmasının tek yolu, metni önce bayt olarak kodlamanızdır. UTF-8 tüm metinler için mantıklı bir kodlamadır, bu yüzden işe yaramalı, değil mi?
Aşağıdaki örnekler Python 3'tedir, böylece dize değişmezleri daha temizdir, ancak aynı sorun hem Python 2 hem de 3'te biraz farklı tezahürlerde mevcuttur.
>>> s = 'naïve \\t test'
>>> print(s.encode('utf-8').decode('unicode_escape'))
naïve test
Eh, bu yanlış.
Metni metne dönüştüren codec bileşenlerini kullanmanın önerilen yeni yolu, codecs.decode
doğrudan aramaktır. Bu yardımcı olur mu?
>>> import codecs
>>> print(codecs.decode(s, 'unicode_escape'))
naïve test
Bir şey değil. (Ayrıca, yukarıdaki Python 2'de bir UnicodeError'dır.)
unicode_escape
Codec, adına rağmen, tüm ASCII olmayan bayt Latin-1 (ISO-8859-1) kodlamada olduğunu varsaymak çıkıyor. Yani bunu şu şekilde yapmanız gerekir:
>>> print(s.encode('latin-1').decode('unicode_escape'))
naïve test
Ama bu korkunç. Bu sizi 256 Latin-1 karakterle sınırlar, sanki Unicode hiç icat edilmemiş gibi!
>>> print('Ernő \\t Rubik'.encode('latin-1').decode('unicode_escape'))
UnicodeEncodeError: 'latin-1' codec can't encode character '\u0151'
in position 3: ordinal not in range(256)
Sorunu çözmek için bir normal ifade eklemek
(Şaşırtıcı bir şekilde, şu anda iki sorunumuz yok.)
Yapmamız gereken şey, unicode_escape
kod çözücüyü yalnızca ASCII metni olduğundan emin olduğumuz şeylere uygulamaktır . Özellikle, bunu yalnızca ASCII metni olması garanti edilen geçerli Python kaçış dizilerine uyguladığımızdan emin olabiliriz.
Plan şu ki, normal bir ifade kullanarak kaçış dizileri bulacağız ve re.sub
onları kaçınılmamış değerleriyle değiştirmek için argüman olarak bir işlev kullanacağız .
import re
import codecs
ESCAPE_SEQUENCE_RE = re.compile(r'''
( \\U........ # 8-digit hex escapes
| \\u.... # 4-digit hex escapes
| \\x.. # 2-digit hex escapes
| \\[0-7]{1,3} # Octal escapes
| \\N\{[^}]+\} # Unicode characters by name
| \\[\\'"abfnrtv] # Single-character escapes
)''', re.UNICODE | re.VERBOSE)
def decode_escapes(s):
def decode_match(match):
return codecs.decode(match.group(0), 'unicode-escape')
return ESCAPE_SEQUENCE_RE.sub(decode_match, s)
Ve bununla:
>>> print(decode_escapes('Ernő \\t Rubik'))
Ernő Rubik
'spam'+"eggs"+'''some'''+"""more"""
işlenmesini tam olarak nasıl beklersiniz ?