2015-12-01 18 views
6

Şu anda Python’u öğreniyorum ve bir Sloven olarak programlarımı test etmek için sıklıkla UTF-8 karakterleri kullanıyorum. Normalde her şey iyi çalışıyor, ama üstesinden gelemediğim bir yaka var. Ben dosyasının üstüne ilan kodlayan var ettik olsa ben bir dize özel karakterler Bir UTF-8 dizgisini tersine çeviren Python

#-*- coding: utf-8 -*- 

a = "čšž" 
print a #prints čšž 
b = a[::-1] 
print b #prints �šō� instead of žšč 

düzeltmek için herhangi bir yolu var mı

içeren ters çalıştığınızda başarısız?

cevap

13

Python 2 dizeleri bayt dizeleri ve UTF-8 kodlanmış metin karakter başına çoklu bayt kullanır. Uçbiriminiz UTF-8 baytları karakter olarak yorumlamayı başardığından, Python'un baytların bir UTF-8 karakteri oluşturduğunu bildiği anlamına gelmez.

Kişisel bytestring 6 baytlardan her iki bayt formu bir karakter: Unicode standardı karakter tanımlanır yere göre değişir kaç bayt UTF-8 kullanır Ancak

>>> a = "čšž" 
>>> a 
'\xc4\x8d\xc5\xa1\xc5\xbe' 

; ASCII karakterleri (Unicode standardındaki ilk 128 karakter) her defasında yalnızca 1 bayta ihtiyaç duyar ve birçok emoji'nin 4 bayta ihtiyacı vardır!

UTF-8 düzeninde her şey; Yukarıdaki bytestring ters kadarıyla UTF-8 standart söz konusu olduğunda bazı anlamsız sonuçlanan bayt tersine çevirir, ancak orta 4 bayt sadece geçerli UTF-8 (š için ve ō) dizileri olmak olur:

>>> a[::-1] 
'\xbe\xc5\xa1\xc5\x8d\xc4' 
-----~~~~~~~~^^^^^^^^#### 
    |  š  ō  | 
    \     \ 
    invalid UTF8 byte opening UTF-8 byte missing a second byte 

Bayt dizesini, tek karakterlerden oluşan unicode nesnesine çözmeniz gerekir. söz konusu nesneyi Geri doğru sonuçlar verir:

b = a.decode('utf8')[::-1] 
print b 

İstediğiniz zaman kodlamak geri UTF-8 tekrar nesne: Unicode, hala sorunların zaman içine çalıştırabilirsiniz

b = a.decode('utf8')[::-1].encode('utf8') 

Not combining characters kullanıldığında metin tersine çevrilir. birleştirerek karakterlerle metin Ters bunun yerine birleşerek karakterinden sonra daha önünde karakterleri birleştirerek bu yerleştirir, böylece yerine yanlış karakteri ile birleştiririz:

>>> print u'e\u0301a' 
éa 
>>> print u'e\u0301a'[::-1] 
áe 

Sen çoğunlukla Unicode verilerini dönüştürerek bu önleyebilirsiniz onun normalize edilmiş form (1-codepoint formları ile kombinasyonları değiştirir) ama dize tersine çevirme ile iyi oynamış diğer egzotik Unicode karakterleri vardır.

+0

Netleştirmek için: _ "ancak dize ters çevrimleriyle etkileşime girmeyen birçok ekootik Unicode karakter var" _ _ _ _ "string reversals ile iyi çalışmaz" _ veya _ "string tersine çevrilmiyor "_? – Piovezan

+0

@Piovezan: Kendime% 100 emin değilim; Ben gidiyorum * dize ters çevirileri ile iyi oynamayın *. –

İlgili konular