Побег из Юникода в эмодзи в Python - PullRequest
0 голосов
/ 06 февраля 2019

Я пытаюсь преобразовать Escaped Unicode в Emojis.

Пример:

>>> emoji = "?"
>>> emoji_text = "\\ud83d\\ude00"
>>> print(emoji)
?
>>> print(emoji_text)
\ud83d\ude00

вместо "\ ud83d \ ude00" Я хотел бы напечатать 100

Я нашел простой трюк, который работает, но не практичен:

>>> import json
>>> json.loads('"\\ud83d\\ude00"')
'?'

1 Ответ

0 голосов
/ 07 февраля 2019

Ваш пример близок к выводу строки ensure_ascii=True в JSON, за исключением необходимости использовать двойные кавычки в строке.Он содержит экранированные Юникодом верхние / нижние суррогаты для символа Юникод выше U + FFFF.

Обратите внимание, что кодек unicode-escape нельзя использовать для преобразования.Это создаст строку Unicode с суррогатами, что недопустимо.Вы не сможете напечатать или закодировать строку для сериализации.

>>> s = "\\ud83d\\ude00"
>>> s = s.encode('ascii').decode('unicode-escape')
>>> s
'\ud83d\ude00'
>>> print(s)  # UnicodeEncodeError: surrogates not allowed

Следующий код заменит суррогаты Unicode их кодовой точкой Unicode.Если у вас есть другие несуррогатные escape-символы Юникода, он также заменит их на их кодовые точки.

import re

def process(m):
    '''process(m) -> Unicode code point

    m is a regular expression match object that has groups below:
     1: high Unicode surrogate 4-digit hex code d800-dbff
     2: low  Unicode surrogate 4-digit hex code dc00-dfff
     3: None
    OR
     1: None
     2: None
     3: Unicode 4-digit hex code 0000-d700,e000-ffff
    '''
    if m.group(3) is None:
        # Construct code point from UTF-16 surrogates
        hi = int(m.group(1),16) & 0x3FF
        lo = int(m.group(2),16) & 0x3FF
        cp = 0x10000 | hi << 10 | lo
    else:
        cp = int(m.group(3),16)
    return chr(cp)

s = "Hello\\u9a6c\\u514b\\ud83d\\ude00"
s = re.sub(r'\\u(d[89ab][0-9a-f]{2})\\u(d[cdef][0-9a-f]{2})|\\u([0-9a-f]{4})',process,s)
print(s)

Вывод:

Hello马克?
...