Как проверить, действительно ли файл UTF-8?
я обрабатываю некоторые файлы данных, которые должны быть действительными UTF-8, но не являются, что приводит к сбою синтаксического анализатора (не под моим контролем). Я хотел бы добавить этап предварительной проверки данных для корректности UTF-8, но я еще не нашел утилиты, которая поможет это сделать.
здесь веб-сервиса в W3C, который кажется мертвым, и я нашел проверку только для Windows инструмент который сообщает о недопустимых файлах UTF-8, но не сообщает, какие строки / символы для исправления.
Я был бы доволен либо инструментом, который я могу бросить и использовать (в идеале кросс-платформенный), либо скриптом ruby/perl, который я могу сделать частью процесса загрузки данных.
5 ответов:
вы можете использовать GNU iconv:
$ iconv -f UTF-8 your_file -o /dev/null
или с более старыми версиями iconv, например на macOS:
$ iconv -f UTF-8 your_file > /dev/null; echo $?
команда возвращает 0, если файл может быть успешно преобразован, и 1 если нет. Кроме того, он будет печатать смещение байта, где произошла недопустимая последовательность байтов.
Edit: выходная кодировка не должна быть указана, предполагается, что это UTF-8.
использовать python и str.функции кодирования / декодирования.
>>> 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')
Как насчет gnu iconv библиотеки? Использование функции iconv (): "во входных данных обнаружена недопустимая многобайтовая последовательность. В этом случае он устанавливает errno в EILSEQ и возвращает (size_t)(-1). * inbuf слева указывает на начало недопустимой многобайтовой последовательности."
EDIT: oh - я пропустил ту часть, где вы хотите язык сценариев. Но для работы в командной строке,iconv утилита должна проверить для вас тоже.
приведенный ниже код C++ основан на одном, опубликованном на многих сайтах через Интернет. Я исправил ошибку в исходном коде и добавил возможность получения как позиции недопустимого символа, так и самого недопустимого символа.
///Returns -1 if string is valid. Invalid character is put to ch. int getInvalidUtf8SymbolPosition(const unsigned char *input, unsigned char &ch) { int nb, na; const unsigned char *c = input; for (c = input; *c; c += (nb + 1)) { if (!(*c & 0x80)) nb = 0; else if ((*c & 0xc0) == 0x80) { ch = *c; return (int)c - (int)input; } else if ((*c & 0xe0) == 0xc0) nb = 1; else if ((*c & 0xf0) == 0xe0) nb = 2; else if ((*c & 0xf8) == 0xf0) nb = 3; else if ((*c & 0xfc) == 0xf8) nb = 4; else if ((*c & 0xfe) == 0xfc) nb = 5; na = nb; while (na-- > 0) if ((*(c + nb) & 0xc0) != 0x80) { ch = *(c + nb); return (int)(c + nb) - (int)input; } } return -1; }