我正在尝试使用Ruby 1.9读取文本文件并将它们转换为我自己的XML结构。我无法控制源文本文件,因此它们可以进行任何编码。
这就是我现在所做的事情:
lines = File.readlines(input_file)
lines.each do |line|
#do something
end
我的文件包含é
字符(xE9)时遇到问题。当我尝试处理相应的行时,我在字符串上调用Invalid byte sequence in UTF-8
时会出现.match(...)
异常。
我尝试使用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
时表示它是UTF-8;我的猜测是我需要使用不同的方式来读取文件,以便它适用于ANSI和UTF-8文件,但我是Ruby初学者,我真的不知道从哪里开始。
答案 0 :(得分:3)
该字符是others中ISO-8859-1和Win-1252字符集的一部分。第二个可能是Windows最受欢迎的字符集,并且是您最有可能的来源。
RUBY_VERSION # => "1.9.2"
这是我的Ruby版本运行以下测试。请注意,在以下示例中,# encoding
行不是注释,它们是指向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关于处理这些事情的事。这是很好的阅读。
现在,回到试图弄清楚角色可能在哪个角色集中:当你只有一个角色,因为它可能同时在几个集合中,很难确定它是哪个集合。如果您有更多字符&gt; =“\ x80”,那么您可以浏览字符集iconv
支持并尝试转换它们。这很麻烦,但我不得不在Perl中做这个,大约在五年前进行一些屏幕刮擦。另一种方法是使用Python chardet
代码。
James Gray的文章链接到推荐rchardet
的文章。
以上例程提到了Mozilla的Charset Detectors,它将为您提供有关处理此问题的更多信息。
答案 1 :(得分:2)
你可以在控制台上试试,这可能是一个暗示:
我使用这样的系统命令来执行此操作:
iconv -f windows-1252 -t UTF-8 "#{csv_file}" > #{Rails.root}/tmp/Kdvakanz-utf8.csv