代码之家  ›  专栏  ›  技术社区  ›  fritzmg

查找自动编码检测的原因(UTF-8与Windows-1252)

  •  1
  • fritzmg  · 技术社区  · 5 年前

    我有一个包含UTF-8编码内容的csv。但是,各种应用程序和系统错误地检测到csv的编码为 Windows-1252 ,它将中断文件中的所有特殊字符(例如umlauts)。

    我可以看到,崇高的文本(在Windows上)也会自动检测到错误的 Windows 1252 编码,当第一次打开文件时,显示混乱的文本,其中应该有特殊字符。

    当我选择 用编码重新打开 UTF-8 一切都会好起来的。

    现在,为了找到错误的来源,我认为这可能有助于弄清楚为什么这些应用程序没有首先自动检测到正确的编码。例如,可能在某个地方有一个误码字符。

    所讨论的csv实际上是magento 2安装的自动生成的产品导出。最近,字符编码中断,我目前正在试图找出发生了什么-因此,我的调查为什么这个输出被检测为 Windows 1252 .

    有没有可靠的方法来弄清楚为什么自动检测应用程序(如升华文本)会采用错误的字符编码?

    1 回复  |  直到 5 年前
        1
  •  2
  •   fritzmg    5 年前

    这就是我最后所做的,以找出为什么文件没有被检测为UTF-8,也就是说,查找没有被编码为UTF-8的字符。由于PHP对我来说更容易使用,所以我决定使用下面的脚本,强制将任何非UTF-8的内容转换为UTF-8,使用非常方便的 neitanod/forceutf8 图书馆。

    $before = file_get_contents('export.csv');
    $after = \ForceUTF8\Encoding::toUTF8($before);
    file_put_contents('export.fixed.csv', $after);
    

    然后我使用了一个类似于beyond-compare的文件比较工具来比较两个产生的CSV,以便更容易地看到哪些字符最初不是用UTF-8编码的。

    这反过来表明,只有一个特定的出口栏受到影响。经过进一步的调查,我发现该列的内容是用php处理的,下面是 preg_replace :

    $value = preg_replace('/([^\pL0-9 -])+/', '', $value);
    

    使用 \p 在正则表达式中有一个未知的副作用:所有特殊字符都被转换为另一种编码。解决这个问题的快速方法是使用 u regex上的标志(请参见 regex pattern modifiers reference )这将强制由此产生的编码 前置替换 成为UTF-8。也见 this answer .