In Python, how to replace all non-UTF-8 characters in a string?

时间:2016-03-28 19:44:18

标签: python mysql encoding utf-8

Update: The real problem is that MySQL utf8 does not support four-byte UTF-8 characters.

There are several questions on this topic, but none of them seems to be my question exactly, except for maybe this one,接受的答案对我不起作用。

我使用MySQLdb模块在​​Python中编码,我想将一些文本放入MySQL数据库中。数据库配置为UTF-8,但文本偶尔包含非UTF-8 四字节-UTF-8字符。

数据库修改的Python代码如下所示:

connection = MySQLdb.connect(
    'localhost',
    'root',
    '',
    'mydatabase',
    charset='utf8',
    use_unicode=True)
cursor = connection.cursor()
cursor.execute(
    'update mytable set entryContent=%s where entryName=%s',
    (entryContent, entryName))
connection.commit()

目前它产生了这个警告:

./myapp.py:233: Warning: Invalid utf8 character string: 'F09286'
  (entry, word))
./myapp.py:233: Warning: Incorrect string value: '\xF0\x92\x86\xB7\xF0\x92...' for column 'entry' at row 1
  (entryname, entrycontent))

当我查看使用mysql命令行客户端实际进入数据库的内容时,我看到在第一次出现非UTF-8 四时截断的内容-byte UTF-8字符。

我不在乎保留非UTF-8 四字节UTF-8字符,所以我想做的就是替换所有非UTF-8 四字节UTF-8字符和一些其他有效的UTF-8字符,因此我可以将文本放入数据库。

3 个答案:

答案 0 :(得分:3)

原来问题是我正在向MySQL提供非UTF-8 字符,但我正在提供四字节UTF-8 字符到MySQL时,它只支持三个(和更少)字节UTF-8字符(according to this documentation

此解决方案保留所有支持的UTF-8字符,并将不支持的UTF-8字符转换为“?”:

>>> print ''.join([c if len(c.encode('utf-8')) < 4 else '?' for c in u'Cognates include Hittite  ‎(lāman)'])
Cognates include Hittite ???? ‎(lāman)
  • 请注意,'ā'保留
  • 请注意''已成为'????'

我可以将此字符串放入MySQL中,而不会出现上述警告(以及不合需要的截断)。

答案 1 :(得分:3)

您需要将表格编码设置为utf8mb4以支持4字节UTF-8编码 - https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html

此外,MySQL驱动程序支持Unicode字符串,因此您应该传递Unicode以从编码细节中释放您的代码:

E.g。

cursor.execute(u'update mytable set entryContent=%s where entryName=%s',
(entryContent.decode("utf-8"), entryName.decode("utf-8")))

理想情况下,entryContententryName在您第一次收到代码时会先在代码中解码为Unicode。例如。打开文件或从网络接收时。

答案 2 :(得分:1)

您可以使用正则表达式删除非ascii字符吗?在评论中使用您的示例:

>>> entry = 'Cognates include Hittite  ‎(lāman)'
>>> entry = ''.join([char if ord(char) < 128 else '' for char in entry])
>>> print entry
Cognates include Hittite  (lman)

这是this answer与其他问题的轻微变化。