转换或删除“非法”的Unicode字符

7

我有一个MSSQL数据库,现在要将其迁移到SQLite/Django。我使用pymssql连接到数据库,并将文本字段保存到本地SQLite数据库。

但是对于某些字符,它会出现错误。我收到了像这样的投诉:

UnicodeDecodeError: 'ascii' codec can't decode byte 0x97 in position 1916: ordinal not in range(128)

有没有方法可以将字符转换为适当的Unicode版本?或者将它们删除?

2个回答

11
当您解码时,只需传递“ignore”即可剥离这些字符。
还有一些其他的剥离/转换方式。
'replace': replace malformed data with a suitable replacement marker, such as '?' or '\ufffd' 

'ignore': ignore malformed data and continue without further notice 

'backslashreplace': replace with backslashed escape sequences (for encoding only) 

测试

>>> "abcd\x97".decode("ascii")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0x97 in position 4: ordinal not in range(128)
>>>
>>> "abcd\x97".decode("ascii","ignore")
u'abcd'

12
即使使用'ignore'参数,Python仍会抛出错误。似乎没有任何解码/编码组合可以去除我完全不关心的任何无用UTF-8字符。 - user1244215

11

当你有一个字节字符串s时,不要直接将其用作Unicode对象,而应该使用正确的编解码器显式地进行转换,例如:

u = s.decode('latin-1')

在接下来的代码中使用u而不是s(可能是写入sqlite的部分)。假设latin-1是用于创建此字节串的编码 - 我们无法猜测,所以请尽量查明;-)。

一般来说,我建议:不要在应用程序中将任何文本作为编码的字节串处理 - 在输入后立即将其解码为Unicode对象,并在必要时在输出之前将其重新编码为字节串。


5
确实,您需要知道您的文本使用哪种编码方式。这几乎是不可避免的。在您的情况下,幸运的是,您的错误信息表明了问题所在。几乎可以确定,由于存在0x97字符,您正在处理微软令人讨厌的cp1252编码。在Latin-1中,此码点代表一个控制字符“END OF GUARDED AREA”,几乎从不使用。如果使用utf-8,则不会看到这种精确的错误,因为0x97不是有效的字符前导字节。而在cp1252中,它是非常常见的短划线。 - jcdyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接