Как получить UTF-16 (десятичный) в Python? - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть Unicode Code Point смайлика, представленный как U + 1F498 :

emoticon = u'\U0001f498'

Я хотел бы получить utf-16 десятичных групп этого символа, которые в соответствии с этот сайт - это 55357 и 56472.

Я пытался сделать print emoticon.encode("utf16"), но мне это совсем не помогло, потому что он дает некоторые другие символы.

ТакжеПопытка декодирования из UTF-8 перед его кодированием в UTF-16 следующим образом print str(int("0001F498", 16)).decode("utf-8").encode("utf16") тоже не помогает.

Как правильно получить десятичные группы utf-16 символа юникода?

Ответы [ 2 ]

0 голосов
/ 30 сентября 2018

В «узкой» сборке Python 2 это просто:

>>> emoticon = u'\U0001f498'
>>> map(ord,emoticon)
[55357, 56472]

Это работает в Python 2 (узкие и широкие сборки) и Python 3:

from __future__ import print_function
import struct

emoticon = u'\U0001f498'
print(struct.unpack('<2H',emoticon.encode('utf-16le')))

Вывод:

(55357, 56472)

Это более общее решение, которое печатает кодовые точки UTF-16 для любой длины строки:

from __future__ import print_function,division
import struct

def utf16words(s):
    encoded = s.encode('utf-16le')
    num_words = len(encoded) // 2
    return struct.unpack('<{}H'.format(num_words),encoded)

emoticon = u'ABC\U0001f498'
print(utf16words(emoticon))

Вывод:

(65, 66, 67, 55357, 56472)
0 голосов
/ 29 сентября 2018

Вы можете encode символ с кодировкой utf-16, а затем преобразовывать каждые 2 байта кодированных данных в целые числа с int.from_bytes (или struct.unpack в Python 2).

Python 3

def utf16_decimals(char, chunk_size=2):
    # encode the character as big-endian utf-16
    encoded_char = char.encode('utf-16-be')

    # convert every `chunk_size` bytes to an integer
    decimals = []
    for i in range(0, len(encoded_char), chunk_size):
        chunk = encoded_char[i:i+chunk_size]
        decimals.append(int.from_bytes(chunk, 'big'))

    return decimals

Python 2 + Python 3

import struct

def utf16_decimals(char):
    # encode the character as big-endian utf-16
    encoded_char = char.encode('utf-16-be')

    # convert every 2 bytes to an integer
    decimals = []
    for i in range(0, len(encoded_char), 2):
        chunk = encoded_char[i:i+2]
        decimals.append(struct.unpack('>H', chunk)[0])

    return decimals

Результат:

>>> utf16_decimals(u'\U0001f498')
[55357, 56472]
...