Python 3和b' \ x92' .decode(' latin1')

时间:2016-10-11 00:51:41

标签: python python-3.x unicode python-unicode

我得到的结果我并不期望解码b' \ x92'使用latin1编解码器。请参阅以下会议:

Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
>>> b'\xa3'.decode('latin1').encode('ascii', 'namereplace')
b'\\N{POUND SIGN}'
>>> b'\x92'.decode('latin1').encode('ascii', 'namereplace')
b'\\x92'
>>> ord(b'\x92'.decode('latin1'))
146

结果解码b' \ xa3'给了我正是我所期待的。但b' \ x92'不是我的预期。我期待b' \ x92' .decode(' latin1')导致U + 2018,但它似乎正在返回U + 0092。

我错过了什么?

3 个答案:

答案 0 :(得分:1)

我只想说明你在这里没有编码。

xa3的序数值为163(十六进制为0xa3)。由于该序数不是7位,因此无法编码为ascii。您的错误处理程序只是将Unicode字符替换为字符的名称。 Unicode角色163映射到£。

另一方面,

'\ x92'的序数值为146.根据this Wikipedia Article,字符不可打印 - 它是C2空间中的私有控制代码。这就解释了为什么它的名字只是文字'\\x92'

顺便说一句,如果你需要角色的名字,最好这样做:

import unicodedata
print unicodedata.name(u'\xa3')

答案 1 :(得分:1)

  

我期待b' \ x92' .decode(' latin1')导致U + 2018

latin1ISO-8859-1的别名。在该编码中,字节0x92映射到字符U + 0092,这是一个不可打印的控制字符。

您可能真正想要的编码是windows-1252,基于它的Microsoft Western code page。在该编码中,0x92是U + 2019,它接近......

(由于历史原因,Web浏览器在两者之​​间也存在混淆,因此出现了进一步的困惑。当网页作为charset=iso-8859-1提供时,网页浏览器实际使用windows-1252。)

答案 2 :(得分:0)

我犯的错误是期望在latin-1中将字符0x92解码为“RIGHT SINGLE QUOTATION MARK”,但事实并非如此。引起混淆的原因是它存在于指定为latin1编码的文件中。现在看来该文件实际上是在windows-1252中编码的。这显然是混淆的常见原因:

http://www.i18nqa.com/debug/table-iso8859-1-vs-windows-1252.html

如果使用正确的编码对字符进行解码,则会获得预期的结果。

>>> b'\x92'.decode('windows-1252').encode('ascii', 'namereplace')
b'\\N{RIGHT SINGLE QUOTATION MARK}'