Пользовательский текстовый декодер UTF8 для старого текстового файла

#python #unicode #utf-8 #character-encoding

#python #юникод #utf-8 #кодировка символов

Вопрос:

У меня есть несколько старых текстовых документов, которые я пытаюсь преобразовать в UTF8 с помощью Python. Он имеет расширение .DOC и был написан с использованием Tandy 1000. Я не смог найти, какую кодировку он использует, поэтому я думаю, что это была какая-то проприетарная кодировка Deskmate. Большая часть текста — символы ascii, а небольшое меньшинство — символы, отличные от ascii. Например, смотрите этот xxd вывод:

 2073 6f75 6c73 a9a9 a920 636f 6d70 6172   souls... compar
 

Используя печатную версию документа, я могу сопоставить байты, отличные от ascii, с их символами Юникода. Например, в приведенном выше xxd выводе 0xa9 является тире em. Есть много других примеров этих символов, отличных от ascii, которые я могу вручную сопоставить с utf8.

Есть предложения по наиболее элегантному подходу к декодированию этих символов? Прямо сейчас у меня есть файл, загруженный в Python bytearray , и мне интересно, есть ли способ предоставить .decode("utf8") функции map, чтобы показать, что, скажем, 0xa9 это 0x2014 (т.Е. em dash)?

Для справки, вот результаты chardetect :

 $ chardetect *DOC
file1.DOC   : ascii with confidence 1.0
file2.DOC   : ISO-8859-1 with confidence 0.7266894615606104
file3.DOC   : ascii with confidence 1.0
file4.DOC   : ascii with confidence 1.0
file5.DOC   : Windows-1252 with confidence 0.7184626436781609
file6.DOC   : Windows-1252 with confidence 0.7278633198811477
file7.DOC   : Windows-1252 with confidence 0.726540670123209
file8.DOC   : ISO-8859-1 with confidence 0.7252491632577166
file9.DOC   : Windows-1252 with confidence 0.7268076883962168
file10.DOC  : Windows-1252 with confidence 0.7252083189387135
file11.DOC  : Windows-1252 with confidence 0.7270349029424267
file12.DOC  : ISO-8859-1 with confidence 0.73
file13.DOC  : KOI8-R with confidence 0.8191677051323929

 

Комментарии:

1. Я бы декодировал с помощью (в качестве примера (cp437 или любая 8-битная кодировка со всеми 256 закодированными значениями) (чтобы вы получили строку). Тогда я буду использовать maketrans()

2. Вероятно, Tandy 1000 был cp437 кодировкой (оригинальная кодировка IBM PC). Это декодируется как ' souls⌐⌐⌐ compar' .

3. (U 2014, Em Dash ) не сопоставляется xa9 ни с какой кодировкой Python (afaik). b"xa9" может быть декодирован в один из следующих символов z ⌐ ر σ ® ę Е Ò ﺏ й Ζ ฉ ゥ ۸ © Š İ Љ Đ ╘ (попытка применить все известные стандартные кодировки Python).

4. Например, bytes.fromhex('2073 6f75 6c73 a9a9 a920 636f 6d70 6172').decode('cp1252') возвращает ' souls©©© compar' или bytes.fromhex('2073 6f75 6c73 a9a9 a920 636f 6d70 6172').decode('cp437') …> ' souls⌐⌐⌐ compar'