Как получить символ из его кодовых точек UTF-16 в Python 3? - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть список кодовых точек UTF-16, которые мне нужно преобразовать в фактические символы, которые они представляют программно.Это кажется невероятно трудным сделать в Python 3.

Например, у меня есть числа 55357 и 56501 для одного персонажа, который я знаю, это смоделированная банкнота: ? Но я понятия не имею, как конвертировать это в Python,Сначала я попробовал chr(55357) + chr(56501), но Python, похоже, предполагает, что он в кодировке UTF-8 и, таким образом, дает мне неработающий Unicode.

Затем я попытался перекодировать строку, но, поскольку она не работает в UTF-8, онадает мне то, что кажется сломанным UTF-16.Если я скажу ему оставить его наедине с (chr(55357) + chr(56501)).encode('utf-8', 'surrogatepass'), я действительно смогу получить действительные байты символа, но он закодирован в ... CESU-8, по причинам, которые я пока не могу понять.Это не та кодировка, которую Python поддерживает изначально, и я не могу найти кодек для ее преобразования.

Думаю, я мог бы записать их на диск и затем прочитать их с правильной кодировкой, но это звучит действительноужасно.

Есть ли разумный способ сделать это в Python 3?

Ответы [ 2 ]

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

Хитрость заключается не в том, чтобы связываться с chr, а в преобразовании в байтовый массив, который затем можно декодировать в строку:

a, b = 55357, 56501
x = a.to_bytes(2, 'little') + b.to_bytes(2, 'little')

print(x.decode('UTF-16'))

Это можно обобщить для любого числа целых чисел:

data = [55357, 56501]
b = bytes([x for c in data for x in c.to_bytes(2, 'little')])
result = b.decode('utf-16')

Причина, по которой что-то вроде chr(55357) + chr(56501) не работает, заключается в том, что chr не предполагает кодирование.Он работает с необработанными кодами Unicode, поэтому вы комбинируете два разных символа.Как указывает другой ответ, вам нужно закодировать эту двухсимвольную строку и повторно декодировать ее, или просто получить байты и декодировать один раз, как я предлагаю.

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

работает следующий код:

cp1 = 55357
cp2 = 56501
(chr(cp1) + chr(cp2)).encode('utf-16', 'surrogatepass').decode('utf-16')
#?
...