UTF-8转换不使用String#encode但是Iconv

时间:2013-04-02 19:39:51

标签: ruby-on-rails ruby

我和Iconv有这个:

git_log = Iconv.conv 'UTF-8', 'iso8859-1', git_log

现在我想将其更改为使用String #catit,因为弃用警告,但我不能,不起作用:

git_log = git_log.encode(Encoding::UTF_8, :invalid => :replace, :undef => :replace, :replace => '')

我以前在这里使用过Iconv,它仍在使用:

https://github.com/gamersmafia/gamersmafia/blob/master/lib/formatting.rb#L244

但是当我用String #coding方法替换这些行时,首先gsub会在UTF-8中引发“无效字节序列”错误。

你知道为什么吗?

2 个答案:

答案 0 :(得分:6)

在致电String#encode时,您未指定源编码。 Ruby使用字符串当前编码作为源,看起来是UTF-8,并且根据the docs

  

请注意,从编码enc到相同编码enc的转换是无操作的,即返回的接收器没有任何更改,并且即使存在无效也不会引发异常字节。

换句话说,调用无效,并将字符串保留在字符串中,编码为ISO-8859-1。下一次调用gsub然后尝试将这些字节解释为UTF-8,并且由于它们无效(它们与ISO-8859-1保持不变),您将看到错误。

String#encode有一个接受源编码作为第二个参数的表单,因此您可以显式指定它,类似于您使用Iconv执行的操作。试试这个:

git_log = git_log.encode(Encoding::UTF_8,
                         Encoding::ISO_8859_1,
                         :invalid => :replace,
                         :undef => :replace,
                         :replace => '')

在这种情况下,你也可以使用!表格,效果相同:

git_log.encode!(Encoding::UTF_8,
                Encoding::ISO_8859_1,
                :invalid => :replace,
                :undef => :replace,
                :replace => '')

答案 1 :(得分:0)

尝试以下方法,如果字符编码错误,则从字符串中删除字符:

invalid_character_indices = []
mystring.each_char.with_index do |char, i|
  invalid_character_indices << i unless char == char.encode(Encoding::UTF_8, Encoding::ISO_8859_1,:invalid => :replace, :undef => :replace, :replace => "")
end
invalid_character_indices.each do |i|
  mystring.delete!(mystring[i])
end