在PHP中定义文本编码,而不是mb_detect_encoding

西里尔字母有几种字符编码。

在Internet上创建站点时,通常使用:

  • utf-8
  • Windows-1251
  • koi8-r

较流行的编码:

  • iso-8859-5
  • ibm866
  • 西里尔字母

这可能不是全部列表,这些是我经常遇到的编码。

有时有必要确定文本的编码。 并且在PHP中甚至有一个用于此的函数:

mb_detect_encoding 

但是,正如m00t在《 在PHP中定义文本编码-现有解决方案概述和另一辆自行车》一文中所写
简而言之,它不起作用。
阅读了m00t文章之后我并没有为它的方法所启发,而是找到了以下解决方案: 确定PHP和Python中的文本编码
正如m00t所说
再次字符代码
我测试了通过字符代码确定编码的功能,结果令我满意,并且我使用此功能已有两年了。

最近,我决定重写使用此功能的项目,在packagist.org cnpait / detect_encoding上找到一个现成的包,其中的编码是使用m00t方法确定的

同时,指定的软件包安装了1200次以上,这意味着定期出现确定文本编码的任务并不只是我一个人。

我将安装此软件包并冷静下来,但我决定“弄糊涂”。

通常,我制作了一个包: onnov / detect-encoding

如何使用它写在README.md中

我将撰写有关对其进行测试并将其与cnpait / detect_encoding软件包进行比较的文章

测试方法


大文本:托尔斯泰-安娜·卡列尼娜
总计-1'701'480个字符

我们删除所有不必要的内容,只保留西里尔字母:

 $text = preg_replace('/[^--]/ui', '', $text); 

剩下1'336'252西里尔字母。

在循环中,我们获取文本的一部分(5、15、30,...个字符),将其转换为已知的编码,然后尝试通过脚本确定编码。 然后正确比较与否。

这是表格的左侧,编码的字符数位于顶部,表格以%%表示可靠性结果
字母->5153060120180270
Windows-125199.1398.8398.5499.0499.7399.93100.0
koi8-r99.8999.98100.0100.0100.0100.0100.0
iso-8859-581.7999.2799.98100.0100.0100.0100.0
ibm86699.8199.99100.0100.0100.0100.0100.0
西里尔字母12.7947.4973.4892.1599.3099.94100.0

Mac Cyrillic最差的准确性,您至少需要60个字符才能确定此编码,准确性为92.15%。 Windows-1251编码的准确性也很低。 这是由于以下事实:表中其字符的编号大大重叠。

幸运的是,没有使用mac-cyrillic和ibm866编码对网页进行编码。

让我们尝试不使用它们:
字母->510153060
Windows-125199.4099.6999.8699.97100.0
koi8-r99.8999.9899.98100.0100.0
iso-8859-581.7996.4199.2799.98100.0

即使在5到10个字母的短句子中,确定的准确性也很高。 对于60个字母的短语,确定的准确性达到100%。 但是,可以非常快速地确定编码,例如,在0.00096秒内检查了长于1,300,000西里尔字符的文本。 (在我的计算机上)

m00t描述的统计方法将显示什么结果:
字母->510153060
Windows-125188.7596.6298.4399.90100.0
koi8-r85.1595.7197.9699.91100.0
iso-8859-588.6096.7798.5899.93100.0

如您所见,确定编码的结果很好。 脚本的速度很高,尤其是在短文本中,而在大文本中,速度明显较差。 超过1,300,000西里尔字符的文本将在0.32秒内被检查。 (在我的计算机上)。

我的发现


  • 两种方法都给出了良好的结果。
  • 该方法的准确性接近。
  • 在大文本中,通过字符代码确定的速度较高,但这并不是很重要,因为 不可能有人会检查如此庞大的文本。
  • 统计方法仍然具有提高编码确定精度的潜力。

使用哪种方法取决于您。 原则上,您可以同时使用两者。

Source: https://habr.com/ru/post/zh-CN466113/


All Articles