Не удается декодировать неправильно закодированную строку с символом М - PullRequest
0 голосов
/ 05 сентября 2018

Я пытаюсь закодировать это:

"LIAISONS Ã  NEW YORK" 

к этому:

"LIAISONS à  NEW YORK"

Выход print(ascii(value)) равен

'LIAISONS \xc3  NEW YORK'

Сначала я пытался кодировать в cp1252, а потом декодировать до utf8, но я получаю следующее:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 9: invalid continuation byte

Я также пытался кодировать в Latin-1 / ISO-8859-2, но это тоже не работает.

Как я могу это сделать?

1 Ответ

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

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

Если ваше входное значение было действительным Mojibake перекодированием из UTF-8 в латинскую кодировку, то у вас было бы два байта для кодовой точки à:

>>> target = "LIAISONS à NEW YORK"
>>> target.encode('UTF-8').decode('latin1')
'LIAISONS Ã\xa0 NEW YORK'

Это потому, что кодировка UTF-8 для à - это C3 A0:

>>> 'à'.encode('utf8').hex()
'c3a0'

По вашим данным, байт A0 (который не отображается на печатный символ в большинстве латинских кодеков) где-то отфильтрован. Вы не можете воссоздать его с нуля, потому что байт C3 пары UTF-8 может предшествовать любому количеству других байтов, что приводит к правильному выводу:

>>> b'\xc3\xa1'.decode('utf8')
'á'
>>> b'\xc3\xa2'.decode('utf8')
'â'
>>> b'\xc3\xa3'.decode('utf8')
'ã'
>>> b'\xc3\xa4'.decode('utf8')
'ä'

и вы не можете легко выбрать один из них, без дополнительной обработки естественного языка. Байты 80-A0 и AD - все действительные байты продолжения в UTF-8 для этого случая, но ни один из этих байтов не приводит к печатному символу Latin-1, поэтому здесь есть по меньшей мере 18 различных возможностей.

...