Итак, я предполагаю, что вы каким-то образом получаете необработанную строку ASCII, которая содержит escape-последовательности с кодовыми единицами UTF-16, которые образуют суррогатные пары, и что вы (по любой причине) хотите преобразовать ее в \UXXXXXXXX
- формат.
Итак, отныне я предполагаю, что ваш ввод (в байтах!) Выглядит следующим образом:
weirdInput = "hello \\ud83d\\ude04".encode("latin_1")
Теперь вы хотите сделать следующее:
- Интерпретировать байты таким образом, что
\uXXXX
штуковины преобразуются в единицы кода UTF-16. Существует raw_unicode_escapes
, но, к сожалению, для исправления суррогатных пар требуется отдельный проход (если честно, я не знаю почему)
- Исправить суррогатные пары, преобразовать данные в действительный UTF-16
- Декодировать как действительный UTF-16
- Снова закодируйте как "raw_unicode_escape"
- Декодировать обратно как старый добрый
latin_1
, состоящий только из старого доброго ASCII с escape-последовательностями Unicode в формате \UXXXXXXXX
.
Примерно так:
output = (weirdInput
.decode("raw_unicode_escape")
.encode('utf-16', 'surrogatepass')
.decode('utf-16')
.encode("raw_unicode_escape")
.decode("latin_1")
)
Теперь, если вы print(output)
, вы получите:
hello \U0001f604
Обратите внимание, что если вы остановитесь на промежуточном этапе:
smiley = (weirdInput
.decode("raw_unicode_escape")
.encode('utf-16', 'surrogatepass')
.decode('utf-16')
)
тогда вы получите строку юникода со смайликами:
print(smiley)
# hello ?
Полный код:
weirdInput = "hello \\ud83d\\ude04".encode("latin_1")
output = (weirdInput
.decode("raw_unicode_escape")
.encode('utf-16', 'surrogatepass')
.decode('utf-16')
.encode("raw_unicode_escape")
.decode("latin_1")
)
smiley = (weirdInput
.decode("raw_unicode_escape")
.encode('utf-16', 'surrogatepass')
.decode('utf-16')
)
print(output)
# hello \U0001f604
print(smiley)
# hello ?