Вопрос по python, mysql, regex – Предупреждение возникает при вставке 4-байтового Unicode в MySQL

7

Посмотрите на следующее:

/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-байтовый юникод:u'\U0001f62a', Набор символов mysql - это utf-8, но при вставке 4-байтового Unicode он усекает вставленную строку. Я гуглил такую проблему и обнаружил, что mysql под 5.5.3 не поддерживает 4-байтовый юникод, и, к сожалению, мой - 5.5.224. Я не хочу обновлять сервер MySQL, поэтому я просто хочу отфильтровать 4-байтовый Unicode в Python, я попытался использовать регулярное выражение, но не получилось. Итак, любая помощь?

@MartijnPieters -unicodedata.name("\U0001f62a") говорит'SLEEPY FACE' (что было быb'\xf0\x9f\x98\xaa' в utf-8), поэтому что-то здесь не так ... mata
Да, и'\xF0\x9F\x91\x8A'.decode('utf8') являетсяu'\U0001f44a', который'FISTED HAND SIGN' :-) Martijn Pieters♦
Это цвет смайликов кулак руки:... Martijn Pieters♦
На самом деле, это сонное лицо. Я очищаю страницы отsina weibo(твиттер в китае) а я такую соскобилSLEEP FACE. Kinka

Ваш Ответ

3   ответа
10

Если MySQL не может обрабатывать коды UTF-8 длиной 4 байта или более, вам придется отфильтровать все символы Юникода по кодам\U00010000; 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: '

Error: User Rate Limit Exceeded.translate() function с таблицей сопоставления, которая содержит толькоNone ценности:

>>> nohigh = { i: None for i in xrange(0x10000, 0x110000) }
>>> example.translate(nohigh)
u'Some example text with a sleepy face: '

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded'\U0000ffff'Error: User Rate Limit Exceeded

Error: User Rate Limit Exceededutf8mb4 codec действительно поддерживает полный диапазон Unicode.

Error: User Rate Limit Exceededhighpoints = re.compile(u'[\U00010000-\U0001ffff]')Error: User Rate Limit Exceeded\UError: User Rate Limit Exceeded Kinka
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededre.compile(u'[\U00010000-\U0010ffff]') "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 244, in _compile raise error, v # invalid expression sre_constants.error: bad character range
Error: User Rate Limit Exceeded\UError: User Rate Limit ExceededuError: User Rate Limit Exceeded Kinka
Error: User Rate Limit Exceeded
2

Я думаю, что вы должны использовать utf8mb4 сопоставления вместо utf8 и запустить

SET NAMES UTF8MB4

после соединения с БД (ссылка на сайт, ссылка на сайт, ссылка на сайт)

Error: User Rate Limit Exceededutf8mb4Error: User Rate Limit ExceededSET NAMESError: User Rate Limit Exceededmysql_real_escape_stringError: User Rate Limit ExceededcharsetError: User Rate Limit Exceededconnect().
0

простая нормализация для строки без регулярных выражений и перевода:

def normalize_unicode(s):
    return ''.join([ unichr(k) if k < 0x10000 else 0xfffd for k in [ord(c) for c in s]])

Похожие вопросы