字符串编码和解码可能来自latin1和utf8

时间:2012-05-09 22:57:15

标签: python mysql unicode utf-8 latin1

我最近偶然发现了一个使用Latin1编码的MySQL数据库,并且在浏览器问号上查看时呈现。为了解决这个问题,我们在所有表上将DB的编码更改为utf8,将Collat​​ion更改为utf8_general_ci,但已存储的数据仍然显示问号符号,所有数据的存储和轮询都从mysql到浏览器由php完成我确保utf8也用于PHP,甚至像许多人在网上建议的那样设置名称utf8,问题是现在我最终得到了奇怪的字符,例如我们知道没有它们的字符串上的ÃÂ'

数据示例

存储

EMMANUEL PE \ xc3 \ u0192 \ xc2 \ u2018A GOMEZ葡萄牙

渲染:

EMMANUELPEÃÂ'AGOMEZ葡萄牙

正确的:

EMMANUELPEÑGGOMEZ葡萄牙


存储

Luis Hern \ xe1ndez-Higareda

渲染:

LuisHernández-Higareda

正确的:

LuisHernández-Higareda


存储

Teresa de Jes \ xc3 \ u0192 \ xc2 \ xbas Galicia G \ xc3 \ u0192 \ xc2 \ xb3mez

渲染:

TeresadeJesúsGaliciaGómez

正确的:

TeresadeJesúsGaliciaGómez


存储

DR。 JOS \ xc3 \ u0192 \ xc2 \ u2030 ABEN \ xc3 \ u0192 \ xc2 \ x81MAR RIC \ xc3 \ u0192 \ xc2 \ x81RDEZ GARC \ xc3 \ u0192 \ xc2 \ x8dA

正确的:

DR。 JOSÉABENÃÂMARRICÃÂRDEZGARCÃÂA

目前我正在使用python从数据库中获取数据,我正在尝试将其标准化为unicode utf8,但我真的输了,就我到达这里而言,我需要转换当前显示的内容如上所示,可读文本的奇怪字符。

我在这里想念的是什么?是无法修复的数据?

功能 https://gist.github.com/2649463

注意: 在所有示例中,有1个正确呈现(如果有任何关于如何解决此问题的建议,请留下那么考虑)

2 个答案:

答案 0 :(得分:4)

试试这个:

print str.encode('cp1252').decode('utf-8').encode('cp1252').decode('utf-8')

使用ipython的示例:

In [49]: a=u'Teresa de Jes\xc3\u0192\xc2\xbas Galicia G\xc3\u0192\xc2\xb3mez'

In [50]: a=u'Teresa de Jes\xc3\u0192\xc2\xbas Galicia G\xc3\u0192\xc2\xb3mez'

In [51]: print a
Teresa de Jesús Galicia Gómez

In [52]: print a.encode('cp1252').decode('utf-8').encode('cp1252').decode('utf-8')
Teresa de Jesús Galicia Gómez

这是“误编码” utf-8 ..

答案 1 :(得分:3)

如果您尝试将无法在latin1中表示的字符插入以该字符编码存储的列中,那些字符将被?不可逆转地替换 - 信息已丢失:您唯一的选择是现在,该列存储在utf8

中,以重新插入/更新数据

但是,你问题中的一些数据并没有多大意义。例如:

  

存储

     

EMMANUEL PE \ xc3 \ u0192 \ xc2 \ u2018A GOMEZ葡萄牙

您是否尝试显示当前存储的字节字符?无论哪种方式,其中一个\u\x转义码都没有意义。

您说原始数据编码为latin1;在该字符集中,Ñ字符编码为0xd1。您说您之后将数据转换为utf8,这会将该字符的编码更改为双字节序列0xc391(这解释了您显示为存储的\xc3,以上;但是,不清楚第二个字节0x91如何变成你的代码段中的序列\u0192\xc2\u2018 *。

我怀疑数据实际上是通过一些进一步的转换,可能在当前存储的转换和用于查看此类存储的任何方式之间。建议您首先确定完全数据库中存储的内容:

SELECT HEX(my_column) FROM my_table WHERE ...

确定后,您将能够更好地了解需要对您的存储数据进行哪些转换(如果有)以使其utf8以及在发生期间发生了哪些不良转换(如果有)存储和检索操作。


*现在阅读了Thanasis Petsas的回答,我发现他已经发现你似乎已经正确解码了utf8 - 编码的字符串为latin1,使用{{1}对结果字符进行编码然后再将这些字节解码为utf8。这确实产生了你所展示的字符序列,但仍然需要了解实际存储的内容以及检索过程中的转换结果。