2010-07-11 13 views
14

संभव डुप्लिकेट:
Python UnicodeDecodeError - Am I misunderstanding encode?पायथन: यूनिकोड के लिए एक स्ट्रिंग को स्वच्छ करें?

मैं एक स्ट्रिंग है कि मैं unicode() समारोह के लिए सुरक्षित बनाने के लिए कोशिश कर रहा हूँ है:

>>> s = " foo “bar bar ” weasel" 
>>> s.encode('utf-8', 'ignore') 

Traceback (most recent call last): 
    File "<pyshell#8>", line 1, in <module> 
    s.encode('utf-8', 'ignore') 
UnicodeDecodeError: 'ascii' codec can't decode byte 0x93 in position 5: ordinal not in range(128) 
>>> unicode(s) 

Traceback (most recent call last): 
    File "<pyshell#9>", line 1, in <module> 
    unicode(s) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0x93 in position 5: ordinal not in range(128) 

मैं ज्यादातर चारों ओर घिसटते हुए कर रहा हूँ यहाँ। स्ट्रिंग से असुरक्षित वर्णों को हटाने के लिए मुझे क्या करने की ज़रूरत है?

कुछ हद तक इस question से संबंधित है, हालांकि मैं इसे से मेरी समस्या का समाधान करने में असमर्थ था।

यह भी विफल रहता है:

>>> s 
' foo \x93bar bar \x94 weasel' 
>>> s.decode('utf-8') 

Traceback (most recent call last): 
    File "<pyshell#13>", line 1, in <module> 
    s.decode('utf-8') 
    File "C:\Python25\254\lib\encodings\utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeDecodeError: 'utf8' codec can't decode byte 0x93 in position 5: unexpected code byte 
+0

मुझे आश्चर्य है कि क्यों 'str' में' एन्कोड 'फ़ंक्शन है, और क्या "एन्कोडिंग" पैरामीटर परिणाम के एन्कोडिंग या इनपुट के एन्कोडिंग को निर्दिष्ट करता है। आप यहाँ क्या करने का प्रयास कर रहे हैं? – Thanatos

+0

कृपया जांचें [यह] (http://stackoverflow.com/questions/368805/python-unicodedecodeerror-am-i-misunderstanding-encode/370199#370199) संबंधित प्रश्न का उत्तर दें: "पायथन यूनिकोडडेकोड एरर - क्या मैं एन्कोड गलत समझ रहा हूं? " – tzot

+0

उन लोगों के लिए जो यूनिकोड विशेष वर्णों को (एक्स) एचटीएमएल में स्वच्छ करने के लिए एक समाधान शिकार करते हैं, 'आप' यूनिकोड str'.encode '' ascii ',' xmlcharrefreplace ')' 'प्रयास करें। – toszter

उत्तर

4

संपादित। ऐसा लगता है कि आपकी स्ट्रिंग को इस तरह से एन्कोड किया गया है कि (बाएं डबल कोटेशन मार्क) \x93 और (दाएं डबल कोटेशन मार्क) \x94 बन जाता है। इस तरह के एक मानचित्रण के साथ codepages की एक संख्या है, CP1250, उनमें से एक है तो आप इसका उपयोग कर सकते हैं: सभी कोडपेज जो नक्शा को \x93 देख here (उन सभी को भी \x94 करने के लिए नक्शे के लिए

s = s.decode('cp1250') 

, जिसे सत्यापित किया जा सकता है here)।

+0

वह कॉल मेरे लिए विफल रहता है (ऊपर देखें) –

+0

@Rosarch ठीक है, अब मैं मूल स्ट्रिंग देखता हूं। मैंने जवाब अपडेट किया है (और इस बीच @ डॉर्डपोर्टर एक ही समाधान के साथ आया था)। – Bolo

+0

कोड पृष्ठों पर अच्छा लिंक। ऐसा लगता है कि वे "विंडोज़" पर सभी भिन्नताएं हैं। यदि आप "पश्चिमी" हैं तो मैं बस 1252 के साथ रहूंगा। – jpsimons

37

अच्छा प्रश्न है। एन्कोडिंग मुद्दे मुश्किल हैं। आइए से शुरू करें "मेरे पास एक स्ट्रिंग है।" अजगर 2 में स्ट्रिंग्स वास्तव में नहीं कर रहे हैं "तार," वे बाइट सरणियों कर रहे हैं। तो आपकी स्ट्रिंग, यह कहां से आई और इसमें एन्कोडिंग क्या है? आपका उदाहरण शाब्दिक में घुंघराले उद्धरण दिखाता है, और मुझे यह भी यकीन नहीं है कि आपने यह कैसे किया। मैं इसे एक पायथन दुभाषिया में पेस्ट करने का प्रयास करता हूं, या इसे ओएस एक्स पर विकल्प- [के साथ टाइप करता हूं, और यह नहीं आता है।

अपने दूसरे उदाहरण को देखते हालांकि, आप क्योंकि UTF-8 में हेक्स 93. का एक चरित्र है कि UTF-8 नहीं किया जा सकता है, किसी भी बाइट 127 की तुलना में अधिक एक multibyte अनुक्रम का हिस्सा है। तो मुझे लगता है कि यह लैटिन -1 होना चाहिए। समस्या यह है कि x93 लैटिन -1 वर्ण सेट में एक चरित्र नहीं है। लैटिन -1 में x7f से x9f तक यह "अमान्य" श्रेणी है जिसे अवैध माना जाता है। हालांकि, माइक्रोसॉफ्ट ने उस अप्रयुक्त रेंज को देखा और वहां "घुंघराले उद्धरण" डालने का फैसला किया। ऐसा करने में उन्होंने "विंडोज -1252" नामक इस समान एन्कोडिंग को बनाया, जो उस अमान्य सीमा में सामान के साथ लैटिन -1 जैसा है।

तो, मान लीजिए कि यह विंडोज -1252 है। अब क्या? String.decode बाइट्स को यूनिकोड में परिवर्तित करता है, इसलिए वह वही है जिसे आप चाहते हैं। आपका दूसरा उदाहरण सही ट्रैक पर था, लेकिन यह असफल रहा क्योंकि स्ट्रिंग यूटीएफ -8 नहीं थी। प्रयास करें:

>>> uni = 'foo \x93bar bar\x94 weasel'.decode("windows-1252") 
u'foo \u201cbar bar\u201d weasel' 
>>> print uni 
foo “bar bar” weasel 
>>> type(uni) 
<type 'unicode'> 

यह सही है, क्योंकि घुंघराले बोली खोलने यूनिकोड U + 201C है। अब जब कि तुम यूनिकोड है, तो आप इसे किसी भी एन्कोडिंग आप चुनते में बाइट्स को क्रमानुसार कर सकते हैं या अगर यह अजगर के भीतर रहते है सिर्फ यूनिकोड के रूप में रखना है (यदि आप तार भर में इसे पारित करने की जरूरत है)। यदि आप यूटीएफ -8 में कनवर्ट करना चाहते हैं, तो विरोध फ़ंक्शन, string.encode का उपयोग करें।

>>> uni.encode("utf-8") 
'foo \xe2\x80\x9cbar bar \xe2\x80\x9d weasel' 

घुंघराले उद्धरण यूटीएफ -8 में एन्कोड करने के लिए 3 बाइट्स लेते हैं। आप यूटीएफ -16 का उपयोग कर सकते हैं और वे केवल दो बाइट होंगे। हालांकि आप ASCII या लैटिन -1 के रूप में एन्कोड नहीं कर सकते हैं, क्योंकि उनमें घुंघराले उद्धरण नहीं हैं।

+1

+1, लेकिन आपको यह भी उल्लेख करना चाहिए कि यह उत्तर पायथन 2.x के लिए विशिष्ट है। 3.x में, 'str' प्रकार का नाम बदलकर 'बाइट्स' हो जाता है और 'यूनिकोड' का नाम बदलकर' str' कर दिया जाता है। पहली बार भ्रमित होने पर, यह परिवर्तन इस तरह की चीज होने की संभावना कम करता है। –

+0

+1 "चलो शुरूआत करें" के लिए +1 मेरे पास एक स्ट्रिंग है "" हाहा –

+1

@ डैनियल नाराज नहीं होना चाहिए, लेकिन मैंने अभी आपके वोट-अप स्पष्टीकरण को वोट दिया है। यह सच है: उपरोक्त पायथन 2.x विशिष्ट है। – jpsimons

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