15

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

4

9 回答 9

20

Mozilla 开发的用于 FireFox 的chardet字符集检测。源代码

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

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

使用 Microsoft 的MLang进行字符编码检测的代码项目 C#示例。

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? ,它有一些有用的内容。

于 2008-12-18T10:40:33.717 回答
6

没有真正可靠的方法,但基本上,作为字节的随机序列(例如,标准 8 位编码的字符串)不太可能是有效的 UTF-8 字符串(如果设置了字节的最高有效位,关于 UTF-8 中可以跟随什么样的字节有非常具体的规则),您可以尝试将字符串解码为 UTF-8,如果没有解码错误,则认为它是 UTF-8。

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

于 2008-12-18T09:15:06.320 回答
5

这个 W3C 页面有一个用于验证 UTF-8 的 perl 正则表达式

于 2008-12-18T09:18:20.963 回答
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);
于 2013-10-11T01:17:31.660 回答
1

在 ruby​​ 中进行字符检测,请安装“chardet”gem

sudo gem install chardet

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

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

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

另请参阅此片段

于 2011-07-18T16:01:28.787 回答
1

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

https://github.com/batterseapower/libcharsetdetect

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

于 2012-06-21T00:10:05.003 回答
1

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

   if(mb_check_encoding($yourDtring, 'UTF-8'))
   {
   //the string is UTF-8
    }
   else 
    {
       //string is not UTF-8
     }
于 2012-06-21T00:16:08.817 回答
1

在 Windows 上,您可以使用MultiByteToWideChar()代码CP_UTF8页和MB_ERR_INVALID_CHARS标志。如果函数失败,则字符串不是有效的 UTF-8。

于 2012-06-21T01:11:53.483 回答
0

作为上一个关于 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();

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

  • 它无法区分 CP 437 和 CP 1252 中的法语文本,即使文本在错误的代码页中打开时完全不可读。
  • 它可以检测以 CP 65001 (UTF-8) 编码的文本,但不能检测以 UTF-16 编码的文本,因此很有把握地错误地报告为 CP 1252!
于 2020-05-11T09:21:21.240 回答