如何检测文本文件中使用的中文编码类型?

3
http://www.gnu.org/software/libiconv/上,有20种中文编码格式:Chinese EUC-CN、HZ、GBK、CP936、GB18030、EUC-TW、BIG5、CP950、BIG5-HKSCS、BIG5-HKSCS:2004、BIG5-HKSCS:2001、BIG5-HKSCS:1999、ISO-2022-CN和ISO-2022-CN-EXT。
我有一个文本文件,它不是UTF-8,而是ASCII编码。我想使用iconv()将其转换为UTF-8,但需要知道源文件的字符编码方式。如果我不懂中文,该怎么办呢?:(
我注意到以下内容:
$str = iconv('GB18030', 'UTF-8', $str);
file_put_contents('file.txt', $str);

生成的文件是UTF-8编码,而我尝试的其他编码(CP950、GBK和EUC-CN)则生成了ASCII文件。这是否意味着iconv能够检测到输入编码与给定字符串不匹配?


请查看mb_detect_encoding - davidkonrad
最可靠的方法可能是让用户决定。 - Pekka
@david 是的,我知道。但我只能用它来查找源代码是否为UTF-8格式。我知道它不是lol.. - thelolcat
http://php.net/manual/de/function.mb-detect-encoding.php - GordonM
@thelolcat,你是对的 - 我尝试了使用http://generator.lorem-ipsum.info/_chinese中的文本进行所有可能的组合,但无法通过mb_detect_erncoding产生除UTF8或ASCII之外的任何结果:( - davidkonrad
显示剩余2条评论
3个回答

3
这可能适合你的需求(但我无法确定)。设置语言环境和 utf8_decode,使用 mb_check_encoding 而非 mt_detect_encoding 看起来会给出一些有用的输出..
// some text from http://chinesenotes.com/chinese_text_l10n.php
// have tried both as string and content loaded from a file
$chinese = '譧躆 礛簼繰 剆坲姏 潧 騔鯬 跠 瘱瘵瘲 忁曨曣 蛃袚觙';
$chinese=utf8_decode($chinese);

$chinese_encodings ='EUC-CN,HZ,GBK,CP936,GB18030,EUC-TW,BIG5,CP950,BIG5-HKSCS,BIG5-HKSCS:2004,BIG5-HKSCS:2001,BIG5-HKSCS:1999,ISO-2022-CN,ISO-2022-CN-EXT';

$encodings = explode(',',$chinese_encodings);

//set chinese locale
setlocale(LC_CTYPE, 'Chinese');

foreach($encodings as $encoding) {
    if (@mb_check_encoding($chinese, $encoding)) {
        echo 'The string seems to be compatible with '.$encoding.'<br>';
    } else {
        echo 'Not compatible with '.$encoding.'<br>';
    }
}

输出

The string seems to be compatible with EUC-CN
The string seems to be compatible with HZ
The string seems to be compatible with GBK
The string seems to be compatible with CP936
Not compatible with GB18030
The string seems to be compatible with EUC-TW
The string seems to be compatible with BIG5
The string seems to be compatible with CP950
Not compatible with BIG5-HKSCS
Not compatible with BIG5-HKSCS:2004
Not compatible with BIG5-HKSCS:2001
Not compatible with BIG5-HKSCS:1999
Not compatible with ISO-2022-CN
Not compatible with ISO-2022-CN-EXT

这只是猜测,但现在它至少似乎能够识别一些中文编码。如果完全无用,请删除。


2
我对中文编码没有任何经验,我知道这个问题被标记为iconv,但如果它能完成工作,那么您可以尝试mb_detect_encoding来检测您的编码;第二个参数是要检查的编码列表,有一个用户自定义的关于中文编码的评论:

对于中国开发者,请注意此函数的第二个参数不包括'GB2312'和'GBK',当检测到一个GB2312字符串时,返回值为'EUC-CN'。

所以,也许如果您明确提供完整的中文编码列表作为第二个参数,它就可以正常工作?它可以像这样工作:
$encoding = mb_detect_encoding($chineseString, 'GB2312,GBK,(...)');
if($encoding) $utf8text = iconv($encoding, 'UTF-8', $str);

您可能还想尝试使用第三个参数 (strict)。


尝试过了,使用了严格模式,从那个列表中返回了EUC-CN、CP936、GB18030... 我不认为一个文件可以有多种编码。 - thelolcat
@thelolcat,你能复制并粘贴使用mb_detect_encoding返回的结果吗?我不知道该函数返回的逗号分隔编码类型字符串。 - Ohgodwhy
它只返回一个,但我尝试改变输入编码的顺序,它也会返回其他的。 - thelolcat

2
检测编码的难度在于八位字节序列可以解码成多种编码中的有效字符,但只有在正确的编码下结果才有意义。我在这种情况下所做的是取出解码后的文本并使用 自动翻译服务 ,看看是否能得到可读的文本或一堆音节。
例如,你可以通过分析输入文本的三元组频率来进行编程处理。像这个库这样的库已经被创建来解决这个问题,也有外部程序可以做到这一点,但我还没有看到任何具有PHP API的东西。然而,这种方法并不是万无一失的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接