2017-10-09 228 views
0

我試圖與八進制轉義的Unicode字符串轉換回正確的Unicode字符串如下,使用Python 3:轉換八位字節字符串轉換爲Unicode字符串,Python 3中

"training\345\256\214\346\210\220\345\276\214.txt"是讀入字符串。

"training完成後.txt"是字符串的實際表現,我正在努力獲得。

然而,SO飛掠之後,似乎建議的解決方案是在以下最無處不在我能找到的Python 3:

decoded_string = bytes(myString, "utf-8").decode("unicode_escape")

不幸的是,這似乎產生了錯誤的Unicode字符串時應用到我的樣本:

'trainingå®Â\x8cæÂ\x88Â\x90å¾Â\x8c.txt'

這似乎很容易在Python 2做字節文字,以及,可惜似乎並沒有在PYT串一樣簡單hon 3.非常感謝,謝謝! :)

回答

1

假設你的出發字符串是Unicode字符串字面用反斜槓,你首先需要一個字節字符串使用unicode-escape編解碼器,但八進制轉義爲UTF-8,所以你需要再次轉換爲字節的字符串,然後解碼爲UTF-8:

>>> s = r'training\345\256\214\346\210\220\345\276\214.txt' 
>>> s 
'training\\345\\256\\214\\346\\210\\220\\345\\276\\214.txt' 
>>> s.encode('latin1') 
b'training\\345\\256\\214\\346\\210\\220\\345\\276\\214.txt' 
>>> s.encode('latin1').decode('unicode-escape') 
'trainingå®\x8cæ\x88\x90å¾\x8c.txt' 
>>> s.encode('latin1').decode('unicode-escape').encode('latin1') 
b'training\xe5\xae\x8c\xe6\x88\x90\xe5\xbe\x8c.txt' 
>>> s.encode('latin1').decode('unicode-escape').encode('latin1').decode('utf8') 
'training完成後.txt' 

注意,latin1編解碼器確實Unicode的一個直接翻譯碼點U + 0000至U + 00FF的字節00FF。

+0

這是偉大的,謝謝! – coltonoscopy

+0

此外,爲了讓我更好理解,您會介紹一些更詳細的內容*爲什麼在解碼爲utf-8之前需要使用拉丁-1編碼? – coltonoscopy

+0

@coltonoscopy在Python 3,你必須明確地編碼爲字節和解碼爲Unicode,所以你不能直接'.decode在Unicode字符串(「Unicode的逃離」)'。 '.encode('latin1')'是將字符串轉換回字節串的一種技巧,將碼點1:1轉換爲字節......假設當然你只有字符串中的U + 0000到U + 00FF碼點。第二個'.encode'('latin1')'是需要的,因爲在解碼之後,你有一個Unicode字符串,其中包含UTF-8編碼數據,所以它必須在解碼爲UTF-8之前轉換回字節。 –