Замена байта в байтовом массиве для исправления кодировки - PullRequest
0 голосов
/ 11 февраля 2019

Я использую ftfy, чтобы исправить неправильную кодировку UTF-8, которая отображается как CP1252, и преобразовать ее в UTF-8 кириллицу, но я обнаружил, что некоторые буквы не могут быть исправлены.

У меня есть строка Ð'010СС199, которую я преобразую в байты и определяю пары b"\xc3\x90'010\xc3\x90\xc2\xa1\xc3\x90\xc2\xa1199", где:

\xc3\x90' -> \xd0\x92 -> Cyrillic В
\xc3\x90\xc2\xa1\ -> \xd0\xa1 -> cyrillic С

Как видите, Ð' длина равна 2. ord не будет работать вэтот случай.

Для использования slice я должен знать, где находится start и end.

Translate здесь также не работает.

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

Оригинал Ð'010СС199 -> преобразование -> вывод В010СС199

РЕДАКТИРОВАТЬ:

    str = "Ð'010СС199"
    str_to_bytes = str.encode("UTF-8")
    print(str_to_bytes)
    # UTF-8 bytes
    # \xc3\x90\xc2\xa0 : \xd0\xa0 -> cyrillic Р
    # \xc3\x90\xc2\xa1 : \xd0\xa1 -> cyrillic С
    # \xc3\x90\xe2\x80\x94' : \xd0\x97 -> cyrillic З
    # \xc3\x90' : \xd0\x92 -> Cyrillic В
    test_str = b"\xc3\x90'010\xc3\x90\xc2\xa1\xc3\x90\xc2\xa1199"
    t1 = test_str.replace(b'\xc3\x90\xc2\xa1', b'\xd0\xa1')
    print(t1)
    dict_cyr = {"Ð'": "P",
                "С":"C"}
    t2 = test_str.translate(test_str)
    print(t2)

Я могу объяснить, как я получил результаты.1. Я использовал 2cyr.com декодер.Но даже в некоторых случаях это не удалось.2. У меня есть строки, переведенные вручную, поэтому я сравнил их и определил, какой байт соответствует букве кириллицы с помощью таблицы UTF-8.

1 Ответ

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

Распространенной проблемой при кодировании / декодировании является кодирование строки в utf-8 и последующее декодирование строки байтов, как если бы это было cp1252 (часто из-за глупого приложения для Windows).

Возможно, что здесь происходит, потому что кириллическое заглавное письмо V ('В' или '\u0412') и кириллическое заглавное письмо ES (or) соответственно переводятся как:

>>> '\u0412'.encode().decode('cp1252')
'Ð’'
>>> '\u0421'.encode().decode('cp1252')
'С'

, что близко к вашей исходной строке, за исключением того, что мое преобразованиеиспользует ПРАВУЮ ОДНОМ ОЦЕНКУ ( или U + 2019), в то время как ваша строка содержит APOSTROPHE (' или U + 0027).

Если строка действительно содержит APOSTROPHE, это может быть вызванопопытка фильтрации нелатинских символов из строки в кодировке cp1252.Недостатком является то, что трудно угадать, является ли апостроф истинным или отфильтрованной правой одинарной кавычкой.

Если он содержит одну кавычку, его можно преобразовать обратно так же просто, как:

>>> 'В010СС199'.encode('cp1252').decode()
'В010СС199'
...