如何识别UTF-8编码的字符串

时间:2008-12-18 09:07:44

标签: unicode encoding utf-8

识别字符串(是或)是否可能是UTF-8编码的最佳方法是什么? Win32 API IsTextUnicode在这里没有多大帮助。此外,该字符串将不具有UTF-8 BOM,因此无法检查。并且,是的,我知道只有ASCII范围以上的字符才会被编码超过1个字节。

9 个答案:

答案 0 :(得分:18)

由FireFox中使用的Mozilla开发的

chardet字符集检测。 Source code

jchardet是来自mozilla自动字符集检测算法的源码的java端口。

NCharDet是Mozilla和FireFox浏览器中使用的C ++ Java端口的.Net(C#)端口。

使用Microsoft的Code project C#进行字符编码检测的

MLang示例。

UTRAC 是一个用c ++编写的命令行工具和库,用于检测字符串编码

cpdetector是一个用于编码检测的java项目

chsdet是一个delphi项目,是一个独立的可执行模块,用于检测给定文本或文件的自动字符集/编码。

另一个有用的帖子指向很多库来帮助您确定字符编码http://fredeaker.blogspot.com/2007/01/character-encoding-detection.html

您还可以查看相关问题How Can I Best Guess the Encoding when the BOM (Byte Order Mark) is Missing?,它有一些有用的内容。

答案 1 :(得分:6)

没有真正可靠的方法,但基本上,随机字节序列(例如标准8位编码中的字符串)不太可能是有效的UTF-8字符串(如果是字节的最高位)如果没有解码错误,你可以尝试将字符串解码为UTF-8并认为它是UTF-8。

确定是否存在解码错误是另一个问题,许多Unicode库只是用问号替换无效字符,而不指示是否发生错误。因此,您需要一种明确的方法来确定解码时是否发生错误。

答案 2 :(得分:5)

This W3C page有一个perl正则表达式,用于验证UTF-8

答案 3 :(得分:2)

在Windows上,您可以将MultiByteToWideChar()CP_UTF8代码页和MB_ERR_INVALID_CHARS标记一起使用。如果函数失败,则字符串无效UTF-8。

答案 4 :(得分:2)

对于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);

答案 5 :(得分:1)

在ruby中进行字符检测 安装'chardet'gem

sudo gem install chardet

这是一个小的ruby脚本,可以在标准输入流上运行chardet。

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

Chardet输出字符集编码的猜测以及统计分析中的置信水平(0-1)

see also this snippet

答案 6 :(得分:1)

基于Mozilla字符集检测器的C / C ++独立库

https://github.com/batterseapower/libcharsetdetect

  

通用字符集检测器(UCSD)   一个库,用于向Mozilla C ++ UCSD库公开C接口和无依赖接口。该库提供了一组高度准确的试探法,试图确定用于编码某些输入文本的字符集。当程序必须处理没有任何编码元数据的输入文件时,这非常有用。

答案 7 :(得分:1)

您没有指定语言,但在PHP中,您可以使用mb_check_encoding

   if(mb_check_encoding($yourDtring, 'UTF-8'))
   {
   //the string is UTF-8
    }
   else 
    {
       //string is not UTF-8
     }

答案 8 :(得分:1)

作为先前关于Win32 mlang DetectInputCodepage()API的answer的附加组件,以下是在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();

但是测试结果非常令人失望:

  • 即使在错误的代码页中打开该文本也是完全不可读的,它也无法区分CP 437和CP 1252中的法语文本。
  • 它可以检测到以CP 65001(UTF-8)编码的文本,但不能检测到以UTF-16正确编码的文本,因为它被误认为是CP 1252!