2015-12-01 9 views
6

मैं वर्तमान में अजगर सीख रहा हूँ पीछे और एक स्लोवेनियाई के रूप में मैं अक्सर अपनी कार्यक्रमों का परीक्षण करने के UTF-8 वर्णों का उपयोग करें। आम तौर पर सब ठीक काम करता है, लेकिन एक पकड़ है जिसे मैं आगे नहीं ले सकता। भले ही मुझे मिल गया है फ़ाइल के शीर्ष पर घोषित एन्कोडिंग यह विफल रहता है जब मैं एक स्ट्रिंग विशेष वर्णअजगर एक UTF-8 स्ट्रिंग

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

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

वहाँ कि ठीक करने के लिए कोई तरीका है जिसमें रिवर्स करने की कोशिश?

उत्तर

13

पायथन 2 तार बाइट स्ट्रिंग्स, और यूटीएफ -8 एन्कोडेड टेक्स्ट प्रति चरित्र एकाधिक बाइट्स का उपयोग करता है। सिर्फ इसलिए कि अपने टर्मिनल पात्रों के रूप में UTF-8 बाइट्स व्याख्या करने के लिए प्रबंधन करता है, इसका मतलब यह नहीं है कि अजगर किस रूप में एक UTF-8 वर्ण बाइट्स के बारे में जानता है।

आपका bytestring 6 बाइट्स के होते हैं, हर दो बाइट्स रूप से एक चरित्र:

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

हालांकि, कितने बाइट्स UTF-8 का उपयोग करता है जहां यूनीकोड ​​मानक में चरित्र परिभाषित किया गया है पर निर्भर करता है; ASCII वर्ण (यूनिकोड मानक में पहले 128 वर्ण) केवल प्रत्येक को 1 बाइट की आवश्यकता है, और कई इमोजी को 4 बाइट चाहिए!

UTF-8 के लिए आदेश में सब कुछ है; ऊपर bytestring पीछे बाइट्स पराजयों, जहाँ तक UTF-8 मानक का सवाल है कुछ निरर्थक शब्दों में जिसके परिणामस्वरूप, लेकिन बीच 4 बाइट सिर्फ हो वैध UTF-8 दृश्यों (š के लिए और ō) होने के लिए:

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

आप एकल वर्ण के होते हैं जो एक unicode वस्तु, के लिए बाइट स्ट्रिंग डिकोड करना होगा। उस वस्तु पीछे आप सही परिणाम देता है:

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

आप कर सकते हैं हमेशा एनकोड वस्तु UTF-8 फिर से वापस करने के लिए:

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

ध्यान दें कि यूनिकोड में, आपको अभी भी समस्या जब में चला सकते हैं पाठ को उलटना, जब combining characters उपयोग किया जाता है। संयोजन पात्रों के साथ पाठ पीछे नहीं बल्कि चरित्र वे के साथ गठबंधन के बाद से सामने अक्षरों के संयोजन उन स्थानों है, इसलिए वे बजाय गलत चरित्र के साथ गठबंधन करेंगे:

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

आप ज्यादातर के लिए यूनिकोड डेटा परिवर्तित करके इस से बच सकते हैं अपने सामान्यीकृत फॉर्म (जो 1-कोडपॉइंट रूपों के साथ संयोजन को प्रतिस्थापित करता है) लेकिन वहां कई अन्य विदेशी यूनिकोड वर्ण हैं जो स्ट्रिंग रिवर्सल के साथ अच्छी तरह से नहीं खेलते हैं।

+0

बस स्पष्ट करने के लिए: _ "लेकिन अन्य विदेशी यूनिकोड वर्ण के बहुत सारे है कि स्ट्रिंग बदलाव के साथ बातचीत नहीं करते हैं" _ साधन _ "स्ट्रिंग बदलाव के साथ अच्छी तरह से काम नहीं करते" _ या _ "स्ट्रिंग बदलाव से प्रभावित नहीं हैं "_? – Piovezan

+0

@Piovezan: मैं खुद 100% निश्चित नहीं हूं; मैं साथ जा रहा हूं * स्ट्रिंग रिवर्सल * के साथ अच्छी तरह से खेलना नहीं है। –

संबंधित मुद्दे