Unicode dizesini Python'daki bir dizeye dönüştürme (fazladan semboller içerir)


504

Bir Unicode dizesini (£ $ gibi ekstra karakterler içeren) Python dizesine nasıl dönüştürebilirsiniz?


2
Hangi Python sürümünü kullandığınızı ve Unicode dizesini çağırdığınızı bilmemiz gerekir. Rahatsızlığa neden olan para birimi simgelerini içeren kısa bir unicode_string üzerinde aşağıdakileri yapın: Python 2.x: print type(unicode_string), repr(unicode_string)Python 3.x: print type(unicode_string), ascii(unicode_string)Ardından sorunuzu düzenleyin ve yukarıdaki yazdırma ifadesinin sonuçlarını kopyalayıp yapıştırın. Sonuçları tekrar yazmayın. Ayrıca HTML'nizin üst kısmına bakın ve şuna benzer bir şey bulabileceğinizi görün: <meta http-equiv = "Content-Type" content = "text / html; charset = iso-8859
John Machin

3
Bir web isteğinden unicode aldığınızdan şüpheliyim. Muhtemelen UTF-8 kodlu Unicode alırsınız.

28
@lutz: "UTF-8 kodlu Unicode" tam olarak unicode değil mi?
jalf

2
Unicode string ve python string ile ne demek istediğinizi açıklığa kavuşturmalısınız (somut örnekler vermek sanırım en iyisi olurdu), yorumlardan anlaşıldığı gibi sorunuzun farklı yorumları var. Bu soruyu sormanızın üzerinden 3,5 yıl geçmesine rağmen neden bunu yapmadığınızı merak ediyorum.
Piotr Dobrogost

6
@jalf: Kodlanmışsa ; artık Unicode değil, örneğin:unicode_string = u"I'm unicode string"; bytestring = unicode_string.encode('utf-8'); unicode_again = bytestring.decode('utf-8')
jfs

Yanıtlar:


573

Görmek unicodedata.normalize

title = u"Klüft skräms inför på fédéral électoral große"
import unicodedata
unicodedata.normalize('NFKD', title).encode('ascii', 'ignore')
'Kluft skrams infor pa federal electoral groe'

24
+1 soruyu ifade olarak cevaplar, @ williamtroup'un unicode'u bir dosyaya kaydedememe sorunu ayrı bir soruya layık tamamen farklı bir soruna benziyor
Mark Roddy

5
@John - bu cevap OP'nin açıklamasından önce gelir.
Dominic Rodger

10
@Mark Roddy: Yazdığı soru, bazı para birimi simgeleri içeren bir "Unicode dizesi" nin (bununla ne anlama gelirse) "Python dizesi" ne (her ne olursa olsun ...) nasıl dönüştürüleceğidir ve bir kaldır-bazı-aksanların delete-other-ascii olmayan karakterler kludge sorusunu cevaplıyor ???
John Machin

13
@JohnMachin Bu, şu sözcük için soru sözcüğünü yanıtlar: Bir dizeyi a'ya dönüştürmenin tek yolu ASCII'de temsil edilemeyen karakterleri bırakmak veya dönüştürmektir. Yani benden +1. unicodestr
Izkata

4
@lzkata: hayır, değil. type(title) == unicode and type(title.encode('utf-8')) == str. Bir dosyaya kaydedilebilen bir baytlama almak için girişi bozmaya gerek yoktur.
jfs

319

ASCII olmayan karakterleri çevirmeniz gerekmiyorsa, kodlamayı ASCII'ye kullanabilirsiniz:

>>> a=u"aaaàçççñññ"
>>> type(a)
<type 'unicode'>
>>> a.encode('ascii','ignore')
'aaa'
>>> a.encode('ascii','replace')
'aaa???????'
>>>

4
Müthiş cevap. Tam olarak ihtiyacım olan şey. Ayrıca, ignorevs etkisini göstermek için harika bir sunumreplace
Jonny Brooks

veya a.encode('ascii', 'xmlcharrefreplace')verir 'aaa&#224;&#231;&#231;&#231;&#241;&#241;&#241;'.
Bob Stein

type(a)olduğu strPython 3.6.8 ve herhangi yoktur encode()yöntemi.
Ali Tou

138
>>> text=u'abcd'
>>> str(text)
'abcd'

Dize yalnızca ascii karakterleri içeriyorsa.


18
Bu sadece pencerelerde işe yarar. Ve ascii olmayan semboller varsa kırılacak.
Vanuan

6
Bu, dizenin içeriği yalnızca bir unicode dizesindeki ascii karakterleri değil, gerçekte unicode ise kırılır. Bunu yapma, her yerde rastgele UnicodeEncodeError istisnaları alırsınız.
Doug

11
Bu cevap bana yardımcı oldu. Dizenizin ascii olduğunu ve onu unicode olmayan bir dizeye geri döndürmeniz gerekiyorsa, bu çok yararlıdır.
VedTopkar

113

Unicode dizeniz varsa ve bunu bir dosyaya veya başka bir serileştirilmiş forma yazmak istiyorsanız, önce diziyi depolanabilecek belirli bir gösterime kodlamanız gerekir . UTF-16 (çoğu Unicode karakter için iki bayt kullanır) veya UTF-8 (karaktere bağlı olarak 1-4 bayt / kod noktası) gibi çeşitli yaygın Unicode kodlamaları vardır. Bu dizeyi belirli bir kodlamaya dönüştürmek için kullanabilirsiniz:

>>> s= u'£10'
>>> s.encode('utf8')
'\xc2\x9c10'
>>> s.encode('utf16')
'\xff\xfe\x9c\x001\x000\x00'

Bu ham bayt dizesi bir dosyaya yazılabilir. Bununla birlikte, geri okurken, hangi kodlamanın içinde olduğunu bilmeniz ve aynı kodlamayı kullanarak kodunu çözmeniz gerektiğini unutmayın.

Dosyalara yazarken, codecs modülünü kullanarak bu manuel kodlama / kod çözme işleminden kurtulabilirsiniz . Bu nedenle, tüm Unicode dizelerini UTF-8'e kodlayan bir dosyayı açmak için şunu kullanın:

import codecs
f = codecs.open('path/to/file.txt','w','utf8')
f.write(my_unicode_string)  # Stored on disk as UTF-8

Bu dosyaları kullanan başka herhangi bir şeyin, bunları okumak istiyorlarsa dosyanın içinde kodlamanın ne olduğunu anlaması gerektiğini unutmayın. Okuma / yazma yapan tek kişi sizseniz bu bir sorun değildir, aksi takdirde dosyaları kullananların anlayabileceği bir biçimde yazdığınızdan emin olun.

Python 3'te, bu dosya erişimi biçimi varsayılan değerdir ve yerleşik openişlev bir kodlama parametresi alır ve metin modunda açılan dosyalar için her zaman Unicode dizelerine (Python 3'teki varsayılan dize nesnesi) / bu diziden çeviri yapar.


58

İşte bir örnek:

>>> u = u'€€€'
>>> s = u.encode('utf8')
>>> s
'\xe2\x82\xac\xe2\x82\xac\xe2\x82\xac'

1
Euro sembolünü utf8burada gösterildiği gibi kodladığımda sonuç sadece soru işaretleri olarak açıklanabilir mi? İşte benim Python sürüm 2.7.13 bir görüntü . ( u"Klüft"Euro gibi değil, diğer unicode nesneleri kodlayabilir miyim ?)
Kırmızı Bezelye

5

Python 3'e geçiş yapmaya hazırsanız / hazırsanız (bazı Python 2 kodlarıyla geriye dönük uyumsuzluk nedeniyle olmayabilirsiniz), herhangi bir dönüştürme yapmanız gerekmez; Python 3'teki tüm metinler Unicode dizeleriyle temsil edilir, bu da u'<text>'sözdiziminin artık kullanılmadığı anlamına gelir . Ayrıca, verileri temsil etmek için kullanılan (kodlanmış bir dize olabilir) gerçekte bayt dizelerine de sahipsiniz.

http://docs.python.org/3.1/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit

(Tabii ki, şu anda Python 3 kullanıyorsanız, sorun muhtemelen metni bir dosyaya nasıl kaydetmeye çalıştığınızla ilgili bir şeydir.)


2
Python'da 3 dizeler Unicode dizeleridir. Asla kodlanmazlar. Aşağıdaki metni yararlı buldum: joelonsoftware.com/articles/Unicode.html

Bir dosyaya kaydetmek istiyor; cevabınız buna nasıl yardımcı oluyor?
John Machin

@lutz: Doğru, Unicode'un kodlama yerine bir karakter haritası olduğunu unutmuştum. @John: Şu anda, tasarrufla ilgili sorunun ne olduğunu bilmek için yeterli bilgi yok. Bir hata mı alıyor? Herhangi bir hata almıyor, ancak dosyayı harici olarak açarken mojibake alıyor mu? Bu bilgi olmadan, sağlanabilecek çok fazla olası çözüm vardır.
JAB

@Cat: Şu anda ne olduğunu bilecek herhangi bir bilgi yok, bir yandan da tasarruf probleminin ne olduğunu. Ondan bazı gerçekler vermesini istedim - cevabımı görün.
John Machin

5

İşte bir örnek kod

import unicodedata    
raw_text = u"here $%6757 dfgdfg"
convert_text = unicodedata.normalize('NFKD', raw_text).encode('ascii','ignore')

bu cevap kabul edilen cevaptan nasıl farklı?
sgauri

3

dosya unicode-esaped dize içeriyor

\"message\": \"\\u0410\\u0432\\u0442\\u043e\\u0437\\u0430\\u0446\\u0438\\u044f .....\",

benim için

 f = open("56ad62-json.log", encoding="utf-8")
 qq=f.readline() 

 print(qq)                          
 {"log":\"message\": \"\\u0410\\u0432\\u0442\\u043e\\u0440\\u0438\\u0437\\u0430\\u0446\\u0438\\u044f \\u043f\\u043e\\u043b\\u044c\\u0437\\u043e\\u0432\\u0430\\u0442\\u0435\\u043b\\u044f\"}

(qq.encode().decode("unicode-escape").encode().decode("unicode-escape")) 
# '{"log":"message": "Авторизация пользователя"}\n'

2
Sadece kullansam bile çalıştı:result.encode().decode('unicode-escape')
Ammad Khalid

0

Hiçbir yanıt benim unicode chars içeren bir dize değişkeni vardı, burada açıkladı ve burada hiçbir encode-decode açıkladı iş yaptı.

Eğer bir Terminalde yaparsam

echo "no me llama mucho la atenci\u00f3n"

veya

python3
>>> print("no me llama mucho la atenci\u00f3n")

Çıktı doğru:

output: no me llama mucho la atención

Ancak bu dize değişkenini yükleyen komut dosyalarıyla çalışmak işe yaramadı.

Kimseye yardım etmesi durumunda benim durumumda işe yarayan buydu :

string_to_convert = "no me llama mucho la atenci\u00f3n"
print(json.dumps(json.loads(r'"%s"' % string_to_convert), ensure_ascii=False))
output: no me llama mucho la atención

json ithal etmek gerekir
pctripsesp
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.