麻烦与文本编码

时间:2012-04-08 05:02:19

标签: haskell

我在使用文本编码方面遇到了一些麻烦。解析一个网站给我一个Data.Text字符串

  

“Project - Fran \ 195 \ 167ois Dubois”,

我需要写一个文件。所以我使用Data.Text.Lazy.Encoding.encodeUtf8将其转换为Bytestring。问题是这会产生乱码输出:

  

“项目 - FrançoisDubois”。

我在这里缺少什么?

2 个答案:

答案 0 :(得分:5)

如果您在Fran\195\167ois中获得Data.Text,则您已经拥有UTF-8编码的François

这是不方便的,因为Data.Text[.Lazy]应该是UTF-16编码的文本,并且两个代码单元195和167被解释为unicode代码点195。 167是'Ã'。 '§'。如果您对文本进行UTF-8编码,则会将这些文本转换为字节序列c383 ([195,131]) resp c2a7 ([194,167])

进入这种情况的最可能方式是,您从网站获得的数据是UTF-8编码,但被解释为ISO-8859-1(拉丁语1)编码(或其他8位编码; 8859 -15也很普遍。)

处理它的正确方法是完全避免这种情况[不幸的是,这可能是不可能的]。

如果您的数据源正确表明其编码 - 如网站应该 - 找出编码并相应地解释数据。如果声明了不正确的编码,那么你当然不走运,如果没有指定编码,你必须猜对了(现在的自然猜测是UTF-8,至少对于使用拉丁字母变体的语言而言)。


如果无法避免这种情况,最简单的解决方法是

  1. 在编码前用所需的序列替换违规序列的出现次数:

    encodeUtf8 $ replace (pack "Fran\195\167ois") (pack "Fran\231ois") contents
    
  2. 假设其他所有内容都是ASCII或无意的UTF-8,请将Text代码单位解释为字节:

    Data.ByteString.Lazy.Char8.pack $ Data.Text.Lazy.unpack contents
    
  3. 前者效率更高,但如果存在许多不同的错误编码(例如由不同的重音字母引起),则会变得不方便。后者仅在假定的情况下工作(Text中没有255以上的代码单元),并且对于长文本效率相当低。

答案 1 :(得分:0)

我不完全确定less是否可以正确显示UTF-8编码字符。 GVim可以。您可以在SO上查看this链接,了解如何在gVim中查看UTF-8数据。

关于能够将其传递给graphviz的另一个问题,我认为您需要按照Graph NonAscii FAQ中的说明在命令行上设置编码。

根据您的解释,我认为数据的持久性没有问题。如果您正确地将编码传递给graphviz,我认为您的问题将得到解决。

P.S:创建答案,因为它更容易创建描述性链接