我想检测一些文本的编码(使用PHP)。为此,我使用mb_detect_encoding()函数。

问题在于,如果我使用mb_detect_order()函数更改可能的编码顺序,则该函数将返回不同的结果。

考虑以下示例

$html = <<< STR
ちょっとのアクセスで落ちてしまったり、サーバー障害が多いレンタルサーバーを選ぶとあなたのビジネス等にかなりの影響がでてしまう可能性があります。特に商売をされている個人の方、法人の方は気をつけるようにしてください
STR;
mb_detect_order(array('UTF-8','EUC-JP', 'SJIS', 'eucJP-win', 'SJIS-win', 'JIS', 'ISO-2022-JP','ISO-8859-1','ISO-8859-2'));
$originalEncoding = mb_detect_encoding($str);
die($originalEncoding); // $originalEncoding = 'UTF-8'

但是,如果更改MB_DETECT_ORDER()中的编码顺序()结果将有所不同:

mb_detect_order(array('EUC-JP','UTF-8', 'SJIS', 'eucJP-win', 'SJIS-win', 'JIS', 'ISO-2022-JP','ISO-8859-1','ISO-8859-2'));        
die($originalEncoding); // $originalEncoding = 'EUC-JP'



所以我的问题是:
为什么会发生?
PHP中有没有办法正确,明确检测文本的编码?

有帮助吗?

解决方案

这就是我期望的。

检测算法可能只是按顺序尝试您指定的编码 mb_detect_order 然后返回第一个元文将有效的第一个。

更智能的东西需要统计方法(我认为通常使用机器学习)。

编辑:请参阅EG 本文 有关更聪明的方法。

由于其重要性,在Mozilla或Internet Explorer等主要的Internet应用程序中已经实现了自动Charset检测。它们非常准确且快速,但是实现在逐案中应用许多特定领域的知识。与他们的方法相反,我们针对的是一种简单的算法,该算法可以均匀地应用于每个CHARSET,并且该算法基于建立良好的标准机器学习技术。我们还研究了语言和Charset检测之间的关系,并比较了基于字节的算法和基于字符的算法。我们使用了幼稚的贝叶斯(NB)和支持向量机(SVM)。

其他提示

并不真地。不同的编码通常具有很大的重叠区域,如果您要测试的字符串完全存在于该重叠中,则两个编码都是可以接受的。

例如,对于字母AZ,UTF-8和ISO-8859-1是相同的。字符串“ Hello”在两个编码中都具有相同的字节顺序。

这就是为什么有一个 mb_detect_order() 首先功能,因为它使您可以说出这些冲突发生时希望发生的事情。您想让“ Hello”成为UTF-8或ISO-8859-1?

记住 mb_detect_encoding() 不知道编码数据是什么。您可能会看到一个字符串,但是该函数本身只看到字节流。因此,它需要猜测编码是什么 - 例如,如果字节仅在0-127范围内,则UTF-8是如果有ASCII字节和128+字节仅成对或更多,则为128+字节等等。

您可以想象,鉴于这种情况,很难可靠地检测到编码。

rihk 说,这就是 mb_detect_order() 功能是适用的 - 您基本上可以提供最佳猜测数据可能是什么。您是否经常使用UTF-8文件?那么,即使您的东西也不可能是UTF-16 mb_detect_encoding() 可以猜到。

您可能还想结帐 手工艺品' 关联 为了更深入的视图。

示例案例: IE浏览器 使用一些有趣的编码猜测是否没有指定任何指定(@link,部分:“自动检测网站的语言”),这会在过去的编码中造成奇怪的行为。如果您在谷歌搜索时,您可能会在其中找到一些有趣的东西。它使一个不错的表演案例甚至统计方法如何可怕地适得其反,以及为什么编码猜测一般是有问题的。

MB_DETECT_ENCODING查看您的MB_DETECT_ORDER()中的第一个Charset条目,然后通过字符循环循环您的输入$ html匹配字符,无论该字符是否属于CharSet的有效字符集中。如果每个角色都匹配,那么它将返回true;如果任何字符失败,它将转移到MB_DETECT_ORDER()中的下一个charset并再次尝试。

Wikipedia的炭火清单 是看到构成每个字符的角色的好地方。

因为这些Charset值重叠(CHAR X8FA1EF在“ UTF-8”和“ EUC-JP”中都存在),即使每个字符集中都是完全不同的字符,也将被视为匹配。因此,除非一个字符值在一个charset中但不存在于另一个字符中,否则mb_detect_encoding无法识别哪些charset无效;并将从您的数组列表中返回可能有效的第一个字符集。

据我所知,没有确定charset的确定方式。如果您对可能会遇到的charset有一个合理的了解,可以帮助PHP的“最佳猜测”方法,并根据每个Charset中的差距(无效字符)相应地订购列表。最好的解决方案是“知道” charset。如果您是从另一个页面刮擦HTML,请在该页面的标题中查找Charset标识符。

如果您真的想变得聪明,可以尝试识别html编写的语言,也许是使用Trigram或n-grams或类似的语言 本文 在php/ir上。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top