【问题标题】:How to read a ANSI text file and convert strings to UTF-8 in Ruby 1.9?如何在 Ruby 1.9 中读取 ANSI 文本文件并将字符串转换为 UTF-8?
【发布时间】:2011-08-23 18:22:09
【问题描述】:

我正在尝试使用 Ruby 1.9 读取文本文件并将它们转换为我自己的 XML 结构。我无法控制源文本文件,因此它们可以采用任何编码。

这是我目前所做的:

lines = File.readlines(input_file)
lines.each do |line|
  #do something
end

我对包含 é 字符 (xE9) 的文件有疑问。当我尝试处理相应的行时,当我在字符串上调用 .match(...) 时,我得到一个 Invalid byte sequence in UTF-8 异常。

我尝试使用Fixing invalid UTF-8 in Ruby, revisited 中描述的解决方法

lines = File.readlines(input_file)
ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
lines.each do |line|
  unless line.empty?
   valid_string = ic.iconv(line + ' ')[0..-2]
   #do something
  end
end

但这只是从行中删除é 字符,这不是我想要的。

我认为真正的问题是文件本身似乎不是 UTF-8 格式,而是使用了一些 ANSI 编码。虽然文件不是 UTF-8,但调用 .encoding 时生成的 line 对象说它是 UTF-8;我的猜测是我需要使用不同的方式来读取文件,以便它适用于 ANSI 和 UTF-8 文件,但我是 Ruby 初学者,我真的不知道从哪里开始。

【问题讨论】:

  • 这是什么 ANSI 东西?这是一个虚构的名字吗?
  • 我认为这是文件使用的实际编码:en.wikipedia.org/wiki/Windows-1252,但我看不到在 ruby​​ 中确定的方法。

标签: ruby encoding


【解决方案1】:

该字符是 ISO-8859-1 和 Win-1252 字符集的一部分,在 others 中。第二个可能是 Windows 上最流行的字符集,也是您最可能的来源。

RUBY_VERSION # => "1.9.2"

这是我运行以下测试的 Ruby 版本。请注意,在以下示例中,# encoding 行不是 cmets,它们是指示 Ruby 在找到未编码的二进制字符时使用哪个字符集:

# encoding: Windows-1252

RUBY_VERSION # => "1.9.2"

asdf = "\xe9"
asdf.encoding # => #<Encoding:Windows-1252>
asdf.encode('UTF-8') # => "é"
asdf.encode('UTF-8').encoding # => #<Encoding:UTF-8>

这显示了 ISO-8859-1 中的字符:

# encoding: ISO-8859-1

RUBY_VERSION # => "1.9.2"

asdf = "\xe9"
asdf.encoding # => #<Encoding:ISO-8859-1>
asdf.encode('UTF-8') # => "é"
asdf.encode('UTF-8').encoding # => #<Encoding:UTF-8>

几年前,James Gray 做了一个series of articles 来处理这些问题。读起来不错。

现在,回到试图弄清楚一个角色可能在哪个字符集中:当您只有一个角色时,因为它可能同时出现在多个集中,所以很难确定它是哪个集。如果您有更多字符 >= "\x80" 那么您可以通过字符集 iconv 支持并尝试转换它们。这很麻烦,但大约五年前我不得不在 Perl 中进行一些屏幕抓取。另一种方法是使用 Python chardet 代码。

James Gray 的文章有一个链接到推荐 rchardet 的文章。

上面的例程提到了Mozilla的Charset Detectors,它会给你更多关于处理这个的信息。

【讨论】:

    【解决方案2】:

    您可以在控制台上尝试一下,这可能是一个提示:

    我用这样的系统命令来做:

    iconv -f windows-1252 -t UTF-8 "#{csv_file}" &gt; #{Rails.root}/tmp/Kdvakanz-utf8.csv

    【讨论】:

    • 当然,你想使用你的编码:)
    • 但要让它工作,我需要知道文件的编码是什么,对吧?
    • @Patrick,当然。 ANSI 编码在文件中没有任何信息; Unicode 带有 BOM(在 UTF-8 上是 hack)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多