gpt4 book ai didi

java - 如何可靠地猜测 MacRoman、CP1252、Latin1、UTF-8 和 ASCII 之间的编码

转载 作者:IT老高 更新时间:2023-10-28 11:27:30 26 4
gpt4 key购买 nike

在工作中,似乎没有一周没有一些与编码相关的阴谋、灾难或灾难。这个问题通常源于程序员认为他们可以在不指定编码的情况下可靠地处理“文本”文件。但你不能。

所以决定从今以后禁止文件名以 *.txt 结尾。或 *.text .他们的想法是,这些扩展会误导普通程序员对编码产生一种沉闷的自满情绪,这会导致处理不当。最好没有
扩展,因为至少你知道你不知道你有什么。

然而,我们不会走那么远。相反,您应该使用以编码结尾的文件名。例如,对于文本文件,这些将类似于 README.ascii , README.latin1 , README.utf8

对于需要特定扩展名的文件,如果可以在文件本身内部指定编码,例如在 Perl 或 Python 中,那么您应该这样做。对于像 Java 源代码这样在文件内部不存在此类功能的文件,您将在扩展名之前放置编码,例如 SomeClass-utf8.java .

对于输出,UTF-8 将是 强烈首选。

但是对于输入,我们需要弄清楚如何处理我们代码库中名为 *.txt 的数千个文件。 .我们想重命名所有这些以适应我们的新标准。但我们不可能把它们全都盯上。所以我们需要一个真正有效的库或程序。

它们有不同的 ASCII、ISO-8859-1、UTF-8、Microsoft CP1252 或 Apple MacRoman。尽管我们知道我们可以判断某些东西是否是 ASCII,并且我们可以很好地了解某些东西是否可能是 UTF-8,但我们对 8 位编码感到困惑。因为我们在混合 Unix 环境(Solaris、Linux、Darwin)中运行,大多数桌面都是 Mac,所以我们有很多烦人的 MacRoman 文件。而这些尤其是一个问题。

一段时间以来,我一直在寻找一种方法来以编程方式确定哪些

  • ASCII
  • ISO-8859-1
  • CP1252
  • 马克罗曼
  • UTF-8

  • 一个文件在里面,我还没有找到可以可靠地区分这三种不同 8 位编码的程序或库。我们可能有超过一千个 MacRoman 文件,所以我们使用的任何字符集检测器都必须能够嗅出它们。我看过的任何东西都无法解决这个问题。我对 ICU charset detector library 寄予厚望,但它无法处理 MacRoman。我还研究了在 Perl 和 Python 中做同样事情的模块,但一次又一次,它总是同一个故事:不支持检测 MacRoman。

    因此,我正在寻找一个现有的库或程序,它可以可靠地确定文件采用这五种编码中的哪一种——最好是更多。特别是它必须区分我引用的三个 3 位编码, 特别是MacRoman .文件99%以上为英文文本;其他语言也有一些,但不多。

    如果是库代码,我们的语言偏好是 Perl、C、Java 或 Python,并按此顺序排列。如果它只是一个程序,那么我们并不真正关心它是什么语言,只要它有完整的源代码,在 Unix 上运行,并且完全不受阻碍。

    有没有其他人遇到过随机编码的无数遗留文本文件的问题?如果是这样,你是如何尝试解决它的,你有多成功?这是我的问题中最重要的方面,但我也感兴趣的是,您是否认为鼓励程序员使用这些文件的实际编码来命名(或重命名)他们的文件将有助于我们在 future 避免这个问题。有没有人试图在制度基础上强制执行这一点,如果是这样,那是否成功,为什么?

    是的,我完全理解为什么鉴于问题的性质,不能保证有明确的答案。对于小文件尤其如此,因为您没有足够的数据来处理。幸运的是,我们的文件很少很小。除了随机 README文件,大多数在 50k 到 250k 的大小范围内,并且许多更大。任何超过几 K 的大小都保证是英文的。

    问题域是生物医学文本挖掘,因此我们有时会处理广泛且极其庞大的语料库,例如 PubMedCentral 的所有开放访问存储库。一个相当大的文件是 BioThesaurus 6.0,大小为 5.7 GB。这个文件特别烦人,因为它几乎都是UTF-8。然而,一些 numbskull 在其中插入了一些 8 位编码的行——我相信是 Microsoft CP1252。在你旅行之前需要很长时间。 :(

    最佳答案

    首先,简单的情况:

    ASCII码

    如果您的数据不包含 0x7F 以上的字节,则它是 ASCII。 (或 7 位 ISO646 编码,但那些已经过时了。)

    UTF-8

    如果您的数据验证为 UTF-8,那么您可以放心地假设它是 UTF-8。由于 UTF-8 的严格验证规则,误报极为罕见。

    ISO-8859-1 与 windows-1252

    这两种编码之间的唯一区别是 ISO-8859-1 具有 C1 控制字符,而 windows-1252 具有可打印字符 €‚ƒ„…†‡ˆ‰Š‹ŒŽ''“”•–—˜™š› -žŸ。我见过很多使用大引号或破折号的文件,但没有一个使用 C1 控制字符。因此,甚至不要理会它们或 ISO-8859-1,只需检测 windows-1252。

    现在你只剩下一个问题了。

    你如何区分MacRoman和cp1252?

    这要棘手得多。

    未定义字符

    在 windows-1252 中不使用字节 0x81、0x8D、0x8F、0x90、0x9D。如果它们发生,则假设数据是 MacRoman。

    相同的字符

    字节 0xA2 (¢)、0xA3 (£)、0xA9 (©)、0xB1 (±)、0xB5 (µ) 在两种编码中恰好相同。如果这些是唯一的非 ASCII 字节,那么选择 MacRoman 还是 cp1252 都没有关系。

    统计方法

    计算您知道是 UTF-8 的数据中的字符(不是字节!)频率。确定最常见的字符。然后用这个数据来判断是cp1252还是MacRoman字符更常见。

    例如,在我刚刚对 100 篇随机英文维基百科文章进行的搜索中,最常见的非 ASCII 字符是 ·•–é°®’èö— .基于这个事实,

  • 字节 0x92、0x95、0x96、0x97、0xAE、0xB0、0xB7、0xE8、0xE9 或 0xF6 建议使用 windows-1252。
  • 字节 0x8E、0x8F、0x9A、0xA1、0xA5、0xA8、0xD0、0xD1、0xD5 或 0xE1 建议使用 MacRoman。

  • 计算 cp1252-suggesting 字节和 MacRoman-suggesting 字节,并选择最大的一个。

    关于java - 如何可靠地猜测 MacRoman、CP1252、Latin1、UTF-8 和 ASCII 之间的编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4198804/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com