Как декодировать escape-строку Юникода в Python 3.6 - PullRequest
0 голосов
/ 23 апреля 2019

Один из файлов библиотеки Python 3.3, email/utils.py имеет следующий код:

_has_surrogates = re.compile(
'([^\ud800-\udbff]|\A)[\udc00-\udfff]([^\udc00-\udfff]|\Z)').search

Это кодируется в байт-коде Python.

В моем кроссплатформенном дизассемблере xdis , который необходим для декомпилятора Python uncompyle6 , я хотел бы создать аналогичную строку из массива байтов, который читается. Когда используя unicodestring = fp.read(strsize) полученная строка:

b'([^\xed\xa0\x80-\xed\xaf\xbf]|\\A)[\xed\xb0\x80-\xed\xbf\xbf]([^\xed\xb0\x80-\xed\xbf\xbf]|\\Z)'

Если попытаться unicodestring.decode('utf-8') Я получу:

** UnicodeDecodeError: 'utf-8' codec can't decode byte 0xed in position 3: invalid continuation byte

Я знаю о добавлении , errors='ignore', но я бы хотел обработать их, а не отбрасывать. И я могу переключиться с utf-8 на latin-1, но тогда вернусь строка:

'([^í\xa0\x80-í¯¿]|\\A)[í°\x80-í¿¿]([^í°\x80-í¿¿]|\\Z)'

что я не уверен, правильно тоже. И даже если это правильно , разве программе Python не понадобится какой-то дополнительный маркер, чтобы указать, что программа содержит строки latin-1?

Возможно, есть решение, использующее unicodestring.decode('utf-8', 'surrogateescape)? Это дает:

 '([^\udced\udca0\udc80-\udced\udcaf\udcbf]|\\A)[\udced\udcb0\udc80-\udced\udcbf\udcbf]([^\udced\udcb0\udc80-\udced\udcbf\udcbf]|\\Z)'

Но здесь я думаю, что мне нужно постобработать строку, чтобы удалить "суррогаты", верно?

...