Как идентифицировать строки в кодировке UTF-8 - PullRequest
14 голосов
/ 18 декабря 2008

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

Ответы [ 8 ]

18 голосов
/ 18 декабря 2008

chardet обнаружение набора символов, разработанное Mozilla для FireFox. Исходный код

jchardet - это java-порт источника из алгоритма автоматического определения кодировки mozilla.

NCharDet - это порт .Net (C #) порта Java C ++, используемый в браузерах Mozilla и FireFox.

Пример кода проекта C # , который использует Microsoft MLang для обнаружения кодировки символов.

UTRAC - инструмент командной строки и библиотека, написанные на c ++ для обнаружения строкового кодирования

cpdetector - это проект Java, используемый для обнаружения кодировки

chsdet является проектом delphi и является автономным исполняемым модулем для автоматического определения кодировки / кодировки заданного текста или файла.

Еще один полезный пост, который указывает на множество библиотек, помогающих определить кодировку символов http://fredeaker.blogspot.com/2007/01/character-encoding-detection.html

Вы также можете взглянуть на связанный с этим вопрос Как лучше всего угадать кодировку, когда отсутствует спецификация (метка порядка следования байтов)? , в ней есть полезное содержимое.

6 голосов
/ 18 декабря 2008

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

Определение наличия ошибок декодирования - это еще одна проблема, многие библиотеки Unicode просто заменяют недопустимые символы знаком вопроса, не указывая, произошла ли ошибка. Поэтому вам нужен явный способ определить, произошла ли ошибка при декодировании или нет.

5 голосов
/ 18 декабря 2008

Эта страница W3C имеет регулярное выражение perl для проверки UTF-8

2 голосов
/ 11 октября 2013

Для Win32 вы можете использовать mlang API, он является частью 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);
2 голосов
/ 21 июня 2012

В Windows вы можете использовать MultiByteToWideChar() с кодовой страницей CP_UTF8 и флагом MB_ERR_INVALID_CHARS. Если функция завершается ошибкой, строка не является допустимой UTF-8.

1 голос
/ 21 июня 2012

Вы не указали язык, но в PHP вы можете использовать mb_check_encoding

   if(mb_check_encoding($yourDtring, 'UTF-8'))
   {
   //the string is UTF-8
    }
   else 
    {
       //string is not UTF-8
     }
1 голос
/ 21 июня 2012

C / C ++ автономная библиотека на основе детектора набора символов Mozilla

https://github.com/batterseapower/libcharsetdetect

Детектор универсального набора символов (UCSD) Библиотека, представляющая интерфейс C и интерфейс без зависимостей для библиотеки Mozilla C ++ UCSD. Эта библиотека предоставляет высокоточный набор эвристик, которые пытаются определить набор символов, используемый для кодирования некоторого входного текста. Это чрезвычайно полезно, когда ваша программа должна обрабатывать входной файл, который поставляется без метаданных кодирования.

1 голос
/ 18 июля 2011

Чтобы определить символ в ruby ​​, установите драгоценный камень 'chardet'

sudo gem install chardet

Вот небольшой скрипт ruby ​​для запуска chardet через стандартный поток ввода.

require "rubygems"
require 'UniversalDetector' #chardet gem
infile =  $stdin.read()
p UniversalDetector::chardet(infile)

Chardet выводит предположение о кодировке набора символов, а также об уровне достоверности (0-1) из своего статистического анализа

см. Также этот фрагмент

...