2013-02-11 8 views
29

मेरे पास कुछ बच निकले हुए स्ट्रिंग्स हैं जिन्हें अनचाहे होने की आवश्यकता है। मैं इसे पायथन में करना चाहता हूं।मैं Python3 में .decode ('string-escape') कैसे करूं?

उदाहरण के लिए, python2.7 में मैं यह कर सकता:

>>> "\123omething special".decode('string-escape') 
'Something special' 
>>> 

मैं python3 में ऐसा कैसे करते हैं? यह काम नहीं करता:

s\000u\000p\000p\000o\000r\000t\[email protected]\000p\000s\000i\000l\000o\000c\000.\000c\000o\000m\000 

और यह में बदल जाते हैं:

"[email protected]" 

बाद मैं रूपांतरण

>>> b"\123omething special".decode('string-escape') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
LookupError: unknown encoding: string-escape 
>>> 

मेरा लक्ष्य इस तरह एक स्ट्रिंग लेने के लिए हाबिल हो रहा है , मैं यह जांचने की जांच करूंगा कि मेरे पास स्ट्रिंग यूटीएफ -8 या यूटीएफ -16 में एन्कोड की गई है या नहीं। आप के बजाय एक str वस्तु के साथ शुरू हैं (अजगर 2.7 यूनिकोड के बराबर)

>>> b"\\123omething special".decode('unicode_escape') 

आप पहली बाइट के लिए सांकेतिक शब्दों में बदलना है, तो डिकोड की आवश्यकता होगी:

+1

इस प्रयास करें:। 'बाइट (" \ विशेष 123omething "," utf-8 ") को डिकोड (" unicode_escape ")' –

+0

आप पूरी तरह निश्चित उन पलायन और नहीं शाब्दिक बाइट्स हैं? –

+0

वे शाब्दिक बाइट हैं!एक बैकस्लैश है, फिर 0, फिर दूसरा 0, फिर एक तीसरा 0 ... मेरे पास एक प्रोग्राम है जो एक बाइनरी फ़ाइल पढ़ता है और इस तरह की जानकारी आउटपुट करता है। यह वास्तव में फ़ाइल में बाइनरी आउटपुट करता है। कभी-कभी फ़ाइल की सामग्री यूटीएफ -8 कोडित होती है और यह बस गुजरती है। लेकिन अगर यह वैध यूटीएफ -8 मान्य नहीं है तो यह इस तरह से एन्कोड किया जाता है। – vy32

उत्तर

28

इसके बजाय आप unicode_escape का उपयोग करना होगा unicode_escape के साथ।

आप अंतिम परिणाम के रूप बाइट्स की जरूरत है, तो आप एक उपयुक्त एन्कोडिंग के लिए फिर से सांकेतिक शब्दों में बदलना करने के लिए (उदाहरण के लिए .encode('latin1'), यदि आप शाब्दिक बाइट मूल्यों के संरक्षण की जरूरत है, पहले 255 यूनिकोड कोड नक्शा 1-पर -1 अंक) होगा ।

आपका उदाहरण वास्तव में यूटीएफ -16 डेटा से बच निकलता है। unicode_escape, वापस latin1 करने से डिकोड (बीओएम बिना यूटीएफ -16 लिटल एन्डियन) utf-16-le से बाइट्स संरक्षित करने के लिए है, तो:

>>> value = b's\\000u\\000p\\000p\\000o\\000r\\000t\\[email protected]\\000p\\000s\\000i\\000l\\000o\\000c\\000.\\000c\\000o\\000m\\000' 
>>> value.decode('unicode_escape').encode('latin1') # convert to bytes 
b's\x00u\x00p\x00p\x00o\x00r\x00t\[email protected]\x00p\x00s\x00i\x00l\x00o\x00c\x00.\x00c\x00o\x00m\x00' 
>>> _.decode('utf-16-le') # decode from UTF-16-LE 
'[email protected]' 
+0

यह मेरी बाइनरी ऑब्जेक्ट को यूनिकोड ऑब्जेक्ट में बदल देता है। मैं इसे एक बाइनरी ऑब्जेक्ट रखना चाहता हूं। ऐसा करने का कोई तरीका? – vy32

+0

@ vy32: डीकोडिंग के बाद इसे एन्कोड करें? आप किस एन्कोडिंग में फिट होने की उम्मीद करते हैं? ASCII, लैटिन 1? –

+0

यह कुछ भी हो सकता है। कार्यक्रम विभिन्न संभावित कोडिंग की जांच करता है। यह एएससीआईआई, यूटीएफ -8, यूटीएफ -16, लैटिन 1, या एक दर्जन अन्य संभावनाएं हो सकती है। – vy32

3

आप बाइट तार पर unicode_escape (या बल्कि उपयोग नहीं कर सकते, आप कर सकते हैं, लेकिन यह नहीं करता है पाइथन 2 पर string_escape जैसा ही हमेशा एक ही चीज़ वापस नहीं करता है) - सावधान रहें!

यह फ़ंक्शन नियमित अभिव्यक्ति और कस्टम प्रतिस्थापन तर्क का उपयोग करके string_escape लागू करता है।

def unescape(text): 
    regex = re.compile(b'\\\\(\\\\|[0-7]{1,3}|x.[0-9a-f]?|[\'"abfnrt]|.|$)') 
    def replace(m): 
     b = m.group(1) 
     if len(b) == 0: 
      raise ValueError("Invalid character escape: '\\'.") 
     i = b[0] 
     if i == 120: 
      v = int(b[1:], 16) 
     elif 48 <= i <= 55: 
      v = int(b, 8) 
     elif i == 34: return b'"' 
     elif i == 39: return b"'" 
     elif i == 92: return b'\\' 
     elif i == 97: return b'\a' 
     elif i == 98: return b'\b' 
     elif i == 102: return b'\f' 
     elif i == 110: return b'\n' 
     elif i == 114: return b'\r' 
     elif i == 116: return b'\t' 
     else: 
      s = b.decode('ascii') 
      raise UnicodeDecodeError(
       'stringescape', text, m.start(), m.end(), "Invalid escape: %r" % s 
      ) 
     return bytes((v,)) 
    result = regex.sub(replace, text) 
12

वर्ष bytestrings को "स्ट्रिंग-भागने" कोडेक नक्शे bytestrings, और क्या इस तरह के कोडेक के साथ क्या करना के बारे में बहस का एक बहुत वहाँ हो गया है, तो यह नहीं वर्तमान में मानक एनकोड/डीकोड इंटरफेस के माध्यम से उपलब्ध है।

लेकिन, कोड अभी भी वहाँ सी एपीआई में है (PyBytes_En/DecodeEscape के रूप में), और यह अभी भी गैर-दस्तावेजी codecs.escape_encode और codecs.escape_decode के माध्यम से अजगर के संपर्क में है।

>>> import codecs 
>>> codecs.escape_decode(b"ab\\xff") 
(b'ab\xff', 6) 
>>> codecs.escape_encode(b"ab\xff") 
(b'ab\\xff', 3) 

इन कार्यों तब्दील bytes वस्तु लौटने के अलावा एक संख्या का संकेत है कि कितने बाइट्स प्रोसेस किया गया ... तुम सिर्फ बाद अनदेखा कर सकते हैं।

>>> value = b's\\000u\\000p\\000p\\000o\\000r\\000t\\[email protected]\\000p\\000s\\000i\\000l\\000o\\000c\\000.\\000c\\000o\\000m\\000' 
>>> codecs.escape_decode(value)[0] 
b's\x00u\x00p\x00p\x00o\x00r\x00t\[email protected]\x00p\x00s\x00i\x00l\x00o\x00c\x00.\x00c\x00o\x00m\x00' 
संबंधित मुद्दे