【问题标题】:Unicode latin1 string encode / decodeUnicode latin1 字符串编码/解码
【发布时间】:2013-02-13 11:13:47
【问题描述】:

在使用 Python (Django) ORM 从未知/旧/不一致的 Mysql 数据库中获取数据到 Postgres utf-8 db 时,我有时会收到错误的编码数据。

目标:格雷戈里

> a
u'gr\xe3\xa9gory'

> print a
grã©gory

我尝试了几种解码/编码技巧,但均未成功:

 > print a.encode('utf-8').decode('latin1')
 grã©gory

 > print a.encode('utf-8').decode('latin1')
 grã©gory

 > print a.decode('latin-1')
UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-3: ordinal not in range(128)

即使有一些 unicode_escape

【问题讨论】:

  • 你是如何获取数据的?你有一个 unicode 实例,里面有错误的字符;您首先要修复产生a 的解码步骤。您显示的代码发生得太晚了。
  • 数据,即使解释为字节而不是 unicode,也不是有效的 UTF8。在该编码中从未遇到过 E3 A9。
  • This 应该可以帮助您在 python 2.x 中使用 unicode;这是“unicode 三明治”的话题。
  • 这两个字节的正确 Unicode 代码点是什么?我们或许可以弄清楚这里出了什么问题,但不知道正确的解释是什么,几乎不可能重建。
  • 最后但同样重要的是,encoding 到 Latin-1 至少会保留“字节”; unicode 代码点 0-255 被编码为具有匹配值的字节,因此您可以将这些字节重新解释为不同的编码。

标签: python utf-8 character-encoding


【解决方案1】:

我猜该字符串在某些时候被错误地转换为小写,将\xc3 更改为\xe3。小写转换在实际为 utf-8 时假定为 latin1 编码。

>>> print 'gr\xc3\xa9gory'.decode('utf8')
grégory

【讨论】:

  • 确实,我在获取的字符串上做了一个 lower()。从 Mysql 读取时,我将尝试在插入级别修复编码/解码。谢谢!
  • @coulix:这是一个至关重要的细节;为什么要先修复小写损坏的数据?
【解决方案2】:

由于问题是 lower(),我可以解决它:

print a.upper().encode('latin1').lower()

【讨论】:

  • 不,'Abcd'.lower().upper()'Abcd' 不同。 OP 在首先修复数据之前不应将其小写。
  • 为了更明确一点:有很多部分 UTF-8 字节可以被解释为拉丁 1 小写字符,而大写那些会破坏 那些字节代替。调用.upper()只会引入更多个错误。
【解决方案3】:

试试这个:

print a.decode('latin1')

【讨论】:

  • 这有什么帮助?
  • a 是一个 unicode 对象;调用.decode() 意味着有一个.encode() first。在这种情况下,数据应该被编码成什么? Python 将默认为 ASCII,对于 E3 和 A9 字节将失败。
猜你喜欢
  • 2023-03-14
  • 2012-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多