【问题标题】:display iso-8859-1 encoded data gives strange characters显示 iso-8859-1 编码数据给出奇怪的字符
【发布时间】:2011-05-23 18:28:43
【问题描述】:

我有一个 ISO-8859-1 编码的 csv 文件,我尝试用 ruby​​ 打开和解析它:

require 'csv'

filename = File.expand_path('~/myfile.csv')
file = File.open(filename, "r:ISO-8859-1")
CSV.parse(file.read, col_sep: "\t") do |row| 
  puts row 
end

如果我在调用 File.open 时省略了编码,我会收到错误

ArgumentError: UTF-8 中的无效字节序列

我的问题是对puts row 的调用显示奇怪的字符而不是挪威字符æ,ø,å:

BOKF.RINGSDATO

如果我在 textmate 中打开文件,我会得到相同的结果,强制它使用 UTF-8 编码。

通过将文件内容分配给字符串,我可以检查用于字符串的编码。正如预期的那样,它显示 ISO-8859-1。

那么当我puts每一行时,为什么它输出字符串为UTF-8? 与 csv 库有关吗?

我使用 ruby​​ 1.9.2。

【问题讨论】:

  • 您的代码在这里运行良好(ubuntu 上的 Ruby 1.9.2)。

标签: ruby encoding csv


【解决方案1】:

通过尝试文档中的不同方法,为自己找到了答案:

require 'csv'

filename = File.expand_path('~/myfile.csv')
File.open(filename, "r:ISO-8859-1") do |file|
  CSV.parse(file.read.encode("UTF-8"), col_sep: "\t") do |row| 
    #                    ↳  returns a copy transcoded to UTF-8.
    puts row 
  end
end

如您所见,我所做的只是在 CSV 解析器获取字符串之前将字符串编码为 UTF-8 字符串。


编辑:
在 macruby-head 上尝试此解决方案,我从 encode() 收到以下错误消息:

Encoding::InvalidByteSequenceError: "\xD8" on UTF-8

即使我在打开文件时指定了编码,macruby 还是使用 UTF-8。 这似乎是一个已知的 macruby 限制:Encoding is always UTF-8

【讨论】:

  • 根据我的经验,第一次处理文件时解码/编码很少会顺利进行。这足以让我把头发扯下来。
【解决方案2】:

ISO-8859-1 和 Win-1252 的字符集非常接近。某些应用程序可以处理文件并转换它吗?或者它可能是从默认为 Win-1252(这是 Window 的标准设置)的机器接收到的?

如果 0x80 到 0x9F 字节范围内没有字符,则感知代码集的软件可能会出错,因此您可以尝试将 file = File.open(filename, "r:ISO-8859-1") 设置为 file = File.open(filename, "r:Windows-1252")。 (我认为“Windows-1252”是正确的编码名称。)

我曾经写过蜘蛛,而 HTML 因标签错误或将一个字符集中的编码二进制字符嵌入另一个字符集而臭名昭著。几年前,在大多数语言实现 UTF-8 和 Unicode 之前,我多次使用一些糟糕的语言来解决这些问题,所以我理解这种挫败感。

ISO/IEC_8859-1, Windows-1252

【讨论】:

  • 如果不确定原始文件是什么字符集,可以使用名为 rchardet 的 gem 来检测源的字符集。
  • 根据我的经验,它不够准确。有一些文本运行无视分类,因为它们是混合的。在解码 RSS 提要时,我曾经遇到过嵌入在 CDATA 块中的 HTML,这些块使用 nnnn; 进行了 HTML 编码字符。将解码为谁知道什么的格式。
  • Windows-1252 没有区别。
  • 那时我会深入了解字节是什么,以及它们是否映射到您期望在该字符串中的单字节或多字节字符。这可能会告诉您使用什么编码。毕竟,有可能你有正确的编码并且这些字符根本不属于,因为有人使用<ALT> 加上他们的数字键盘注入了字节。
  • Ø 由 \xD8 表示,Æ 由 \xC6 表示,它告诉你任何事情。
【解决方案3】:

也许您可以在解析之前使用 Iconv 将文件内容转换为 UTF-8?

【讨论】:

  • 也许我可以,但如果应用程序可以按原样读取文件会更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-26
  • 2014-01-18
  • 1970-01-01
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多