iconv не может распознать допустимый символ utf-8 как utf-8.

Вопрос или проблема

Мои входные данные следующие (как сгенерировано командой hexdump):

000000f0  69 61 6e e2 80 99 73 20  65 79 65 73 20 61 62 72  |ian...s eyes abr|

Когда я открываю этот html () файл в Firefox, он отображает эти символы как:

ian’s eyes abr

Согласно ссылке https://superuser.com/questions/1237545/characters-in-email-displayed-like-e2-80-99, “E2 80 99 это последовательность шестнадцатеричных значений, кодирующих правую апостроф (’) в UTF-8”.

Этот сайт подтверждает: https://www.utf8-chartable.de/unicode-utf8-table.pl?start=8192&number=128

Когда я запускаю эту команду iconv на файле, содержащем эти символы:

iconv -f UTF-8 -t ISO-8859-15 test_chapter.html > blah.html

Я получаю вывод:

iconv: illegal input sequence at position 243

и содержимое “blah.html” обрывается точно там, где должен быть апостроф.

Итак, подведем итог, интернет говорит, что это допустимая последовательность байтов для UTF-8, но iconv не согласен.

Кто-нибудь может помочь мне понять, что происходит? Это баг в iconv?

Кстати, когда я использую этот html файл с kindlegen для создания файла AZW, символ отображается неправильно. Весь интернет говорит мне, что мне нужно сконвертировать файл в UTF-8, но, насколько я могу судить, он уже в этом формате!

Ваш комментарий:

возможно, проблема в конвертации в ISO-8859-15, а не в конвертации из UTF-8

на правильном пути. Проблема в том, что в ISO-8859-15 нет символа . Наиболее похожий символ '. См. что говорит man 1 iconv в Debian 12, который я использую:

Если строка //TRANSLIT добавляется к to-encoding, символы, которые конвертируются, подвергаются транслитерации при необходимости и если это возможно. Это означает, что когда символ не может быть представлен в целевой кодировке, он может быть заменен на один или несколько похожих символов. Символы, находящиеся вне целевой кодировки и которые нельзя транслитерировать, заменяются на знак вопроса (?) в выходных данных.

Используйте -t ISO-8859-15//TRANSLIT тогда.

В качестве доказательства концепции, это работает для меня (в локали pl_PL.UTF-8):

printf '%s\n' 'ian’s eyes abr' | iconv -f UTF-8 -t ISO-8859-15//TRANSLIT

Вывод ian's eyes abr (с новой строкой в конце). Так получилось, что представление этой конкретной строки идентично в ISO-8859-15 и в UTF-8, поэтому я решил не усложнять команду дополнительной передачей через iconv -f ISO-8859-15 -t UTF-8.

.

Ответ или решение

Если вы сталкиваетесь с проблемой, когда iconv не распознает корректный UTF-8 символ и выводит сообщение об ошибке, важно понимать, что проблема, скорее всего, связана с несовместимостью символьных наборов, а не с неверной интерпретацией UTF-8.

Контекст проблемы

Давайте посмотрим на ваш пример:

  • Исходные данные в hex: 69 61 6e e2 80 99 73 20 65 79 65 73 20 61 62 72

    • Здесь e2 80 99 — это кодировка символа правой одинарной кавычки (’), что подтверждается стандартами UTF-8.
  • Командная строка:

    iconv -f UTF-8 -t ISO-8859-15 test_chapter.html > blah.html
    • Вы получаете ошибку: iconv: illegal input sequence at position 243.

Анализ проблемы

Причина ошибки заключается в том, что символ правая одинарная кавычка (’) присутствует в UTF-8, но его нет в ISO-8859-15, на который вы пытаетесь конвертировать.

Решение проблемы

Вы можете воспользоваться опцией //TRANSLIT, чтобы приблизить символ к доступному в ISO-8859-15, заменив его на обычную одинарную кавычку (‘).

Пример команды:

iconv -f UTF-8 -t ISO-8859-15//TRANSLIT test_chapter.html > blah.html

Это позволит iconv попытаться преобразовать отсутствующие в ISO-8859-15 символы в схожие, если это возможно.

Подводя итог

  1. Причина: Символ отсутствует в ISO-8859-15.
  2. Решение: Использование //TRANSLIT для замены на схожий символ.
  3. Проверка: Убедитесь, что ваш HTML файл действительно в UTF-8, используя команду:
    file -bi test_chapter.html

Заключение

Сделайте акцент на корректной кодировке ваших данных и учитывайте ограничения целевой кодировки при преобразованиях. Используйте //TRANSLIT для обеспечения максимальной совместимости, если конечный набор символов этого требует.

Оцените материал
Добавить комментарий

Капча загружается...