我在文本编码方面遇到了一些麻烦。解析网站给了我一个 Data.Text 字符串
“项目 - Fran\195\167ois Dubois”,
我需要写入文件。所以我使用 Data.Text.Lazy.Encoding.encodeUtf8 将其转换为字节串。问题是这会产生乱码输出:
“项目 - François Dubois”。
我在这里想念什么?
我在文本编码方面遇到了一些麻烦。解析网站给了我一个 Data.Text 字符串
“项目 - Fran\195\167ois Dubois”,
我需要写入文件。所以我使用 Data.Text.Lazy.Encoding.encodeUtf8 将其转换为字节串。问题是这会产生乱码输出:
“项目 - François Dubois”。
我在这里想念什么?
如果你已经Fran\195\167ois
进入你Data.Text
的François
.
这很不方便,因为Data.Text[.Lazy]
应该是 UTF-16 编码的文本,并且两个代码单元 195 和 167 分别被解释为 unicode 代码点 195。167 分别是 'Ã' 。'§'。如果您对文本进行 UTF-8 编码,则会将它们分别转换为字节c383 ([195,131])
序列c2a7 ([194,167])
。
遇到这种情况的最可能的方法是您从网站获得的数据是 UTF-8 编码的,但被解释为 ISO-8859-1(拉丁 1)编码(或其他 8 位编码;8859-15 是也很普遍)。
处理它的正确方法是完全避免这种情况[不幸的是,这可能是不可能的]。
如果您的数据源正确地说明了它的编码 - 作为一个网站应该 - 找出编码并相应地解释数据。如果声明了不正确的编码,那么您当然不走运,如果没有指定编码,您必须猜对(现在自然猜测是 UTF-8,至少对于使用拉丁字母变体的语言而言)。
如果无法避免这种情况,最简单的解决方法是
在编码之前用所需的序列替换出现的违规序列:
encodeUtf8 $ replace (pack "Fran\195\167ois") (pack "Fran\231ois") contents
假设其他一切都是 ASCII 或无意的 UTF-8,将Text
代码单元解释为字节:
Data.ByteString.Lazy.Char8.pack $ Data.Text.Lazy.unpack contents
前者效率更高,但如果有许多不同的错误编码(例如,由不同的重音字母引起),就会变得不方便。后者仅在假定的情况下有效( 中没有超过 255 的代码单元Text
)并且对于长文本效率很低。
我不完全确定是否less
可以正确显示 UTF-8 编码的字符。GVim 可以。您可以在 SO 上查看此链接以了解如何在 gVim 中查看 UTF-8 数据。
关于能够将其传递给 graphviz 的另一个问题,我认为您需要在命令行上设置编码,如Graph NonAscii FAQ中所述。
根据您的解释,我认为数据的持久化方式没有问题。如果您将编码正确传递给graphviz,我认为您的问题将得到解决。
PS:创建答案,因为创建描述性链接更容易