请看以下内容:
/home/kinka/workspace/py/tutorial/tutorial/pipelines.py:33: Warning: Incorrect string
value: '\xF0\x9F\x91\x8A\xF0\x9F...' for column 't_content' at row 1
n = self.cursor.execute(self.sql, (item['topic'], item['url'], item['content']))
字符串'\xF0\x9F\x91\x8A
实际上是一个4字节的unicode:u'\U0001f62a'
。 mysql的字符集是utf-8但是插入4字节的unicode会截断插入的字符串。
我搜索了这个问题,发现5.5.3下的mysql不支持4字节unicode,不幸的是我的是5.5.224。
我不想升级mysql服务器,所以我只想过滤python中的4字节unicode,我尝试使用正则表达式但失败了。
那么,有什么帮助吗?
答案 0 :(得分:10)
如果MySQL无法处理4字节或更多字节的UTF-8代码,则必须在代码点\U00010000
上过滤掉所有unicode字符; UTF-8将低于该阈值的代码点编码为3个字节或更少。
您可以使用正则表达式:
>>> import re
>>> highpoints = re.compile(u'[\U00010000-\U0010ffff]')
>>> example = u'Some example text with a sleepy face: \U0001f62a'
>>> highpoints.sub(u'', example)
u'Some example text with a sleepy face: '
或者,您可以将.translate()
function与仅包含None
值的映射表一起使用:
>>> nohigh = { i: None for i in xrange(0x10000, 0x110000) }
>>> example.translate(nohigh)
u'Some example text with a sleepy face: '
但是,创建转换表会占用大量内存并花费一些时间来生成;因为正则表达式方法更有效,所以可能不值得你努力。
这一切都假设你使用的是UCS-4编译的python。如果您的python是使用UCS-2支持编译的,那么您只能在正则表达式中使用最多'\U0000ffff'
的代码点,并且您将永远不会遇到此问题。
我注意到,从MySQL 5.5.3开始,新添加的utf8mb4
codec确实支持完整的Unicode范围。
答案 1 :(得分:2)
答案 2 :(得分:0)
没有正则表达式的字符串的简单规范化和翻译:
def normalize_unicode(s):
return ''.join([ unichr(k) if k < 0x10000 else 0xfffd for k in [ord(c) for c in s]])