Ruby:从ANSI到UTF-8解析yaml

时间:2015-09-23 11:18:39

标签: ruby encoding utf-8 yaml

问题:

我有可以用UTF-8或ANSI编码的yaml文件test.yml

:excel:
  "Test":
    "eins_Ä": :eins
    "zwei_ä": :zwei

当我加载文件时,我需要将其编码为UTF-8,因此尝试转换所有字符串:

require 'yaml'
file = YAML::load_file('C:/Users/S61256/Desktop/test.yml')

require 'iconv'
CONV = Iconv.new("UTF-8", "ASCII")

class Test

    def convert(hash)
        hash.each{ |key, value| 
            convert(value) if value.is_a? Hash
            CONV.iconv(value) if value.is_a? String
            CONV.iconv(key) if key.is_a? String
        }
    end

end

t = Test.new
converted = t.convert(file)

p file
p converted

但是当我尝试运行这个示例脚本时,它会打印出来:

in 'iconv': eins_- (Iconv:IllegalSequence)

问题:

1。为什么会出现错误以及如何解决?

2。是否有另一种(更合适的)方式来获取UTF-8中的文件内容?

注意: 我需要这个代码与Ruby 1.8以及Ruby 2.2兼容。对于Ruby 2.2,我会用String :: encode替换所有的Iconv内容,但这是另一个主题。

1 个答案:

答案 0 :(得分:1)

处理错误编码文件的最简单方法是以原始编码读取它,转换为UTF-8然后传递给接收方(在这种情况下为YAML):

▶ YAML.load File.read('/tmp/q.yml', encoding: 'ISO-8859-1').force_encoding 'UTF-8'
#⇒ {:excel=>{"Test"=>{"eins_Ä"=>:eins, "zwei_ä"=>:zwei}}}

对于Ruby 1.8,您应该使用Iconv,但整个过程(按原样,比编码,而不是yaml-load)保持不变。