Как проверить, является ли файл действительным UTF-8? - PullRequest
62 голосов
/ 22 сентября 2008

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

На W3C есть веб-служба , которая, кажется, мертва, и я нашел инструмент проверки только для Windows, который сообщает о недействительных файлах UTF-8, но не сообщает какие строки / символы исправить.

Я был бы рад либо инструменту, который я мог бы добавить и использовать (в идеале кроссплатформенный), либо скрипту ruby ​​/ perl, который я могу сделать частью моего процесса загрузки данных.

Ответы [ 4 ]

83 голосов
/ 22 сентября 2008

Вы можете использовать GNU iconv:

$ iconv -f UTF-8 your_file -o /dev/null

Или с более старыми версиями iconv, например, в macOS:

$ iconv -f UTF-8 your_file > /dev/null; echo $?

Команда вернет 0, если файл может быть успешно преобразован, и 1, если нет. Кроме того, он распечатает смещение байта, в котором произошла неправильная последовательность байтов.

Редактировать : Выходную кодировку указывать не нужно, предполагается, что это UTF-8.

10 голосов
/ 22 сентября 2008

Используйте функции python и str.encode | decode.

>>> a="γεια"
>>> a
'\xce\xb3\xce\xb5\xce\xb9\xce\xb1'
>>> b='\xce\xb3\xce\xb5\xce\xb9\xff\xb1' # note second-to-last char changed
>>> print b.decode("utf_8")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.5/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 6: unexpected code byte

В выданном исключении информация запрошена в свойстве .args.

>>> try: print b.decode("utf_8")
... except UnicodeDecodeError, exc: pass
...
>>> exc
UnicodeDecodeError('utf8', '\xce\xb3\xce\xb5\xce\xb9\xff\xb1', 6, 7, 'unexpected code byte')
>>> exc.args
('utf8', '\xce\xb3\xce\xb5\xce\xb9\xff\xb1', 6, 7, 'unexpected code byte')
9 голосов
/ 26 мая 2016

Вы можете использовать isutf8 из коллекции moreutils .

$ apt-get install moreutils
$ isutf8 your_file

В сценарии оболочки используйте переключатель --quiet и проверьте состояние выхода, которое равно нулю для файлов, которые являются действительными utf-8.

4 голосов
/ 22 сентября 2008

Как насчет библиотеки gnu iconv ? Использование функции iconv (): «На входе встречается недопустимая многобайтовая последовательность. В этом случае он устанавливает errno в EILSEQ и возвращает (size_t) (- 1). * В inbuf остается указание на начало недопустимой многобайтовой последовательности. «

РЕДАКТИРОВАТЬ: о - я пропустил ту часть, где вы хотите язык сценариев. Но для работы с командной строкой утилита iconv должна проверяться и для вас.

...