Как лучше всего определить, может ли строка (есть или) быть закодирована в UTF-8? Win32 API IsTextUnicode здесь не особо помогает. Кроме того, в строке не будет спецификации UTF-8, поэтому ее нельзя будет проверить. И, да, я знаю, что только символы выше диапазона ASCII кодируются более чем 1 байтом.
Ничего особенного - ищу общий метод. Но если вы можете дать что-то, что работает для определенного языка, пожалуйста, присоединяйтесь.
И вы не найдете спецификации в начале потока UTF-8, это не имеет смысла, поскольку UTF-8 одинаков, независимо от порядка байтов.
Да, но некоторые по-прежнему называют его «спецификацией». Я предпочитаю называть это «преамбулой» (как .NET) или «подписью». Это все еще может быть полезно для идентификации кодировки.





Нет действительно надежного способа, но в основном случайная последовательность байтов (например, строка в стандартной 8-битной кодировке) вряд ли будет действительной строкой UTF-8 (если установлен самый старший бит байта, существуют очень конкретные правила относительно того, какие байты могут следовать ему в UTF-8), вы можете попробовать декодировать строку как UTF-8 и считать, что это UTF-8, если нет ошибок декодирования.
Определение наличия ошибок декодирования - это еще одна проблема, многие библиотеки Unicode просто заменяют недопустимые символы вопросительным знаком, не указывая, произошла ли ошибка. Поэтому вам нужен явный способ определения, произошла ли ошибка при декодировании или нет.
Любая библиотека Unicode правильный должна заменять неизвестные символы на U + FFFD, а не с буквальным знаком вопроса.
Эта страница W3C имеет регулярное выражение Perl для проверки UTF-8
Если вы читаете поток и у вас может не быть начала, вам следует либо потерять \ A в начале, либо добавить ". {0,5}?" сразу после него, чтобы захватить первый усеченный символ.
Я бы порекомендовал сделать это, используя стандартную библиотеку Unicode языка вместо того, чтобы повторно реализовывать ее с помощью регулярных выражений.
Обнаружение набора символов Chardet, разработанное Mozilla, используемое в FireFox. Исходный код
Jchardet - это java-порт источника из алгоритма автоматического определения кодировки Mozilla.
NCharDet - это порт .Net (C#) порта Java для языка C++, используемого в браузерах Mozilla и FireFox.
Пример Код проекта C#, который использует Microsoft MLang для обнаружения кодировки символов.
UTRAC - это инструмент командной строки и библиотека, написанная на C++ для определения кодировки строк.
cpdetector - это Java-проект, используемый для обнаружения кодировки
чсдет - это проект delphi и автономный исполняемый модуль для автоматического определения кодировки / кодировки данного текста или файла.
Еще один полезный пост, который указывает на множество библиотек, которые помогут вам определить кодировку символов http://fredeaker.blogspot.com/2007/01/character-encoding-detection.html
Вы также можете взглянуть на связанный вопрос Как я могу лучше всего угадать кодировку, если отсутствует спецификация (метка порядка байтов)?, в нем есть полезное содержание.
Извините, что комментирую ответ 10-летней давности, но у меня есть небольшая поправка. cpdetector не является библиотекой Delphi (написан на Java). Если кто-то ищет определение кодировки Delphi, возможно, стоит изучить чсдет.
@AdamHenderson спасибо за исправление, я обновил вопрос
Для обнаружения символов в рубине установите гем 'chardet'
sudo gem install chardet
Вот небольшой скрипт на Ruby для запуска chardet поверх стандартного входного потока.
require "rubygems"
require 'UniversalDetector' #chardet gem
infile = $stdin.read()
p UniversalDetector::chardet(infile)
Chardet выводит предположение о кодировке набора символов, а также уровень достоверности (0-1) из своего статистического анализа.
Автономная библиотека C / C++ на основе детектора набора символов Mozilla
https://github.com/batterseapower/libcharsetdetect
Universal Character Set Detector (UCSD) A library exposing a C interface and dependency-free interface to the Mozilla C++ UCSD library. This library provides a highly accurate set of heuristics that attempt to determine the character set used to encode some input text. This is extremely useful when your program has to handle an input file which is supplied without any encoding metadata.
Вы не указали язык, но в PHP вы можете использовать mb_check_encoding
if (mb_check_encoding($yourDtring, 'UTF-8'))
{
//the string is UTF-8
}
else
{
//string is not UTF-8
}
В Windows вы можете использовать MultiByteToWideChar() с кодовой страницей CP_UTF8 и флагом MB_ERR_INVALID_CHARS. Если функция не работает, строка недопустима в кодировке UTF-8.
Для Win32 вы можете использовать API mlang, это часть Windows и поддерживается в Windows XP. Интересно то, что он дает вам статистику того, насколько вероятно, что ввод будет в определенной кодировке:
CComPtr<IMultiLanguage2> lang;
HRESULT hr = lang.CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER);
char* str = "abc"; // EF BB BF 61 62 63
int size = 6;
DetectEncodingInfo encodings[100];
int encodingsCount = 100;
hr = lang->DetectInputCodepage(MLDETECTCP_NONE, 0, str, &size, &encodings, &encodingsCount);
Я только что провел несколько тестов подпрограммы DetectEncodingInfo (), и результаты очень плохие: * Он не может различать французские тексты в CP 437 и CP 1252, даже если текст полностью нечитаем, если открыть в неправильном кодовая страница. * Он может обнаруживать текст, закодированный в CP 65001 (UTF-8), но не текст в UTF-16, который ошибочно сообщается как CP 1252 с большой уверенностью!
В качестве дополнения к предыдущему отвечать о Win32 mlang DetectInputCodepage () API, вот как его вызвать на C:
#include <Mlang.h>
#include <objbase.h>
#pragma comment(lib, "ole32.lib")
HRESULT hr;
IMultiLanguage2 *pML;
char *pszBuffer;
int iSize;
DetectEncodingInfo lpInfo[10];
int iCount = sizeof(lpInfo) / sizeof(DetectEncodingInfo);
hr = CoInitialize(NULL);
hr = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, &IID_IMultiLanguage2, (LPVOID *)&pML);
hr = pML->lpVtbl->DetectInputCodepage(pML, 0, 0, pszBuffer, &iSize, lpInfo, &iCount);
CoUninitialize();
Но результаты тестов очень неутешительные:
Этот код на самом деле не компилируется.
Конечно, необходим минимальный код. Вы должны интегрировать в свою собственную действующую функцию.
На каком языке вы пытаетесь это сделать?