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

纠正由错误编码引起的错误数据的最佳方法

  •  4
  • ercan  · 技术社区  · 14 年前

    我有一组数据,其中包含混乱的文本字段,因为在从一个数据库到另一个数据库的许多导入/导出过程中存在编码错误。大多数错误是由utf-8转换为iso-8859-1引起的。奇怪的是,这些错误并不一致:单词' 缅因 '显示为' 缅因 '在某个地方,也作为' M_ “在别的地方。

    在sql server中有什么技巧可以纠正这种错误吗?我能想到的第一件事就是利用 COLLATE 条款,以便 阿尔法 被解释为 γ ,但我不知道怎么做。如果不可能在db级别进行,您知道有什么工具可以帮助进行批量更正吗?(没有手动查找/替换工具,而是一种以某种方式猜测并更正错误文本的工具)

    4 回复  |  直到 9 年前
        1
  •  4
  •   Mathias Bynens    12 年前

    我已经进去了 确切地 同样的位置。生产mysql服务器设置为latin1,旧数据设置为latin1,新数据设置为utf8,但存储在latin1列中,然后添加utf8列,每行可以包含任意数量的编码。

    最大的问题是没有一个单一的解决方案可以解决所有问题,因为许多传统编码对不同的字符使用相同的字节。这意味着你将不得不诉诸启发式。在我的 Utf8Voodoo 类中有一个很大的字节数组,从127到255,也就是传统的单字节编码非ascii字符。

    // ISO-8859-15 has the Euro sign, but ISO-8859-1 has also been used on the
    // site. Sigh. Windows-1252 has the Euro sign at 0x80 (and other printable
    // characters in 0x80-0x9F), but mb_detect_encoding never returns that
    // encoding when ISO-8859-* is in the detect list, so we cannot use it.
    // CP850 has accented letters and currency symbols in 0x80-0x9F. It occurs
    // just a few times, but enough to make it pretty much impossible to
    // automagically detect exactly which non-ISO encoding was used. Hence the
    // need for "likely bytes" in addition to the "magic bytes" below.
    
    /**
     * This array contains the magic bytes that determine possible encodings.
     * It works by elimination: the most specific byte patterns (the array's
     * keys) are listed first. When a match is found, the possible encodings
     * are that entry's value.
     */
    public static $legacyEncodingsMagicBytes = array(
        '/[\x81\x8D\x8F\x90\x9D]/' => array('CP850'),
        '/[\x80\x82-\x8C\x8E\x91-\x9C\x9E\x9F]/' => array('Windows-1252', 'CP850'),
        '/./' => array('ISO-8859-15', 'ISO-8859-1', 'Windows-1252', 'CP850'),
    );
    
    /**
     * This array contains the bytes that make it more likely for a string to
     * be a certain encoding. The keys are the pattern, the values are arrays
     * with (encoding => likeliness score modifier).
     */
    public static $legacyEncodingsLikelyBytes = array(
        // Byte | ISO-1  | ISO-15 | W-1252 | CP850
        // 0x80 | -      | -      | €      | Ç
        '/\x80/' => array(
            'Windows-1252' => +10,
        ),
        // Byte | ISO-1  | ISO-15 | W-1252 | CP850
        // 0x93 | -      | -      | “      | ô
        // 0x94 | -      | -      | ”      | ö
        // 0x95 | -      | -      | •      | ò
        // 0x96 | -      | -      | –      | û
        // 0x97 | -      | -      | —      | ù
        // 0x99 | -      | -      | ™      | Ö
        '/[\x93-\x97\x99]/' => array(
            'Windows-1252' => +1,
        ),
        // Byte | ISO-1  | ISO-15 | W-1252 | CP850
        // 0x86 | -      | -      | †      | å
        // 0x87 | -      | -      | ‡      | ç
        // 0x89 | -      | -      | ‰      | ë
        // 0x8A | -      | -      | Š      | è
        // 0x8C | -      | -      | Œ      | î
        // 0x8E | -      | -      | Ž      | Ä
        // 0x9A | -      | -      | š      | Ü
        // 0x9C | -      | -      | œ      | £
        // 0x9E | -      | -      | ž      | ×
        '/[\x86\x87\x89\x8A\x8C\x8E\x9A\x9C\x9E]/' => array(
            'Windows-1252' => -1,
        ),
        // Byte | ISO-1  | ISO-15 | W-1252 | CP850
        // 0xA4 | ¤      | €      | ¤      | ñ
        '/\xA4/' => array(
            'ISO-8859-15' => +10,
        ),
        // Byte | ISO-1  | ISO-15 | W-1252 | CP850
        // 0xA6 | ¦      | Š      | ¦      | ª
        // 0xBD | ½      | œ      | ½      | ¢
        '/[\xA6\xBD]/' => array(
            'ISO-8859-15' => -1,
        ),
        // Byte | ISO-1  | ISO-15 | W-1252 | CP850
        // 0x82 | -      | -      | ‚      | é
        // 0xA7 | §      | §      | §      | º
        // 0xFD | ý      | ý      | ý      | ²
        '/[\x82\xA7\xCF\xFD]/' => array(
            'CP850' => +1
        ),
        // Byte | ISO-1  | ISO-15 | W-1252 | CP850
        // 0x91 | -      | -      | ‘      | æ
        // 0x92 | -      | -      | ’      | Æ
        // 0xB0 | °      | °      | °      | ░
        // 0xB1 | ±      | ±      | ±      | ▒
        // 0xB2 | ²      | ²      | ²      | ▓
        // 0xB3 | ³      | ³      | ³      | │
        // 0xB9 | ¹      | ¹      | ¹      | ╣
        // 0xBA | º      | º      | º      | ║
        // 0xBB | »      | »      | »      | ╗
        // 0xBC | ¼      | Œ      | ¼      | ╝
        // 0xC1 | Á      | Á      | Á      | ┴
        // 0xC2 | Â      | Â      | Â      | ┬
        // 0xC3 | Ã      | Ã      | Ã      | ├
        // 0xC4 | Ä      | Ä      | Ä      | ─
        // 0xC5 | Å      | Å      | Å      | ┼
        // 0xC8 | È      | È      | È      | ╚
        // 0xC9 | É      | É      | É      | ╔
        // 0xCA | Ê      | Ê      | Ê      | ╩
        // 0xCB | Ë      | Ë      | Ë      | ╦
        // 0xCC | Ì      | Ì      | Ì      | ╠
        // 0xCD | Í      | Í      | Í      | ═
        // 0xCE | Î      | Î      | Î      | ╬
        // 0xD9 | Ù      | Ù      | Ù      | ┘
        // 0xDA | Ú      | Ú      | Ú      | ┌
        // 0xDB | Û      | Û      | Û      | █
        // 0xDC | Ü      | Ü      | Ü      | ▄
        // 0xDF | ß      | ß      | ß      | ▀
        // 0xE7 | ç      | ç      | ç      | þ
        // 0xE8 | è      | è      | è      | Þ
        '/[\x91\x92\xB0-\xB3\xB9-\xBC\xC1-\xC5\xC8-\xCE\xD9-\xDC\xDF\xE7\xE8]/' => array(
            'CP850' => -1
        ),
    /* etc. */
    

    然后循环字符串中的字节(而不是字符)并保留分数。如果你想知道更多的信息,请告诉我。

        2
  •  1
  •   PP.    14 年前

    下载iconv-您可以获得win32和unix/linux的二进制文件。它是一个命令行工具,接受一个源文件,在指定输入编码和输出编码之后,将为您执行到stdout的必要转换。

    我发现自己经常使用这个工具将utf-16(作为sql server 2005导出文件的输出)转换为ascii。

    您可以从这里下载: http://gnuwin32.sourceforge.net/packages/libiconv.htm

        3
  •  0
  •   Douglas Leeder    14 年前

    考虑到数据的复杂性(一行/条目上有多个编码)。我认为您必须导出/转储数据,然后对其运行处理。

    我认为最好的方法是一系列的人工替换。也许某种拼写更正代码可以找到所有错误-然后您可以添加显式更正代码。然后重复直到拼写检查停止查找错误?

    (显然,在字典中添加任何正确的单词,以便进行拼写检查)。

        4
  •  0
  •   dwt    9 年前

    看一看 https://github.com/LuminosoInsight/python-ftfy -它很擅长做一个启发性的修正,将照顾到 相当地 一些比你看到数据的小样本时所期望的更丑陋的东西。