unicode_escape
सामान्य रूप से काम नहीं करता है
यह पता चला है कि string_escape
या unicode_escape
समाधान सामान्य रूप से काम नहीं करता है - विशेष रूप से, यह वास्तविक यूनिकोड की उपस्थिति में काम नहीं करता है।
यदि आप सुनिश्चित कर सकते हैं कि प्रत्येक गैर-एएससीआईआई चरित्र बच जाएगा (और याद रखें, पहले 128 वर्णों से परे कुछ भी गैर-एएससीआईआई है), unicode_escape
आपके लिए सही काम करेगा। लेकिन अगर आपके स्ट्रिंग में पहले से ही कोई शाब्दिक गैर-एएससीआईआई अक्षर हैं, तो चीजें गलत हो जाएंगी।
unicode_escape
मूल रूप से बाइट्स को यूनिकोड पाठ में बदलने के लिए डिज़ाइन किया गया है। लेकिन कई स्थानों में - उदाहरण के लिए, पायथन स्रोत कोड - स्रोत डेटा पहले से ही यूनिकोड पाठ है।
एकमात्र तरीका यह सही ढंग से काम कर सकता है यदि आप पाठ को पहले बाइट्स में एन्कोड करते हैं। यूटीएफ -8 सभी पाठों के लिए समझदार एन्कोडिंग है, इसलिए काम करना चाहिए, है ना?
निम्नलिखित उदाहरण पायथन 3 में हैं, ताकि स्ट्रिंग शाब्दिक क्लीनर हो, लेकिन पायथन 2 और 3 दोनों पर थोड़ी अलग अभिव्यक्तियों के साथ एक ही समस्या मौजूद है।
>>> s = 'naïve \\t test'
>>> print(s.encode('utf-8').decode('unicode_escape'))
naïve test
खैर, यह गलत है।
पाठ में डिकोड करने वाले कोडेक्स का उपयोग करने का नया अनुशंसित तरीका codecs.decode
सीधे कॉल करना है। क्या उससे मदद हुई?
>>> import codecs
>>> print(codecs.decode(s, 'unicode_escape'))
naïve test
हर्गिज नहीं। (इसके अलावा, उपरोक्त पाइथन 2 पर एक यूनिकोडर्रम है)
unicode_escape
कोडेक, जैसा कि इसके नाम के बावजूद, पता चला है ग्रहण करने के लिए है कि सभी गैर- ASCII बाइट्स लैटिन -1 (ISO-8859-1) एन्कोडिंग में कर रहे हैं। तो आपको इसे इस तरह करना होगा:
>>> print(s.encode('latin-1').decode('unicode_escape'))
naïve test
लेकिन यह भयानक है। यह आपको 256 लैटिन -1 वर्णों तक सीमित करता है, जैसे कि यूनिकोड का आविष्कार कभी नहीं हुआ था!
>>> 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)
समस्या को हल करने के लिए एक नियमित अभिव्यक्ति जोड़ना
(हैरानी की बात है, अब हमें दो समस्याएं नहीं हैं।)
हमें जो करने की आवश्यकता है, केवल unicode_escape
डिकोडर को उन चीजों पर लागू करें जिन्हें हम ASCII पाठ के लिए निश्चित हैं। विशेष रूप से, हम इसे केवल वैध पायथन एस्केप सीक्वेंस पर लागू करने के लिए सुनिश्चित कर सकते हैं, जो कि ASCII पाठ होने की गारंटी है।
योजना यह है कि हम एक नियमित अभिव्यक्ति का उपयोग करके एस्केप सीक्वेंस प्राप्त करेंगे, और एक फ़ंक्शन का उपयोग तर्क के रूप में re.sub
उन्हें उनके अनपेक्षित मान से बदलने के लिए करेंगे।
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)
और उसके साथ:
>>> print(decode_escapes('Ernő \\t Rubik'))
Ernő Rubik
'spam'+"eggs"+'''some'''+"""more"""
संसाधित किया जाएगा?