41

Encoding::UndefinedConversionError - "\xC2" from ASCII-8BIT to UTF-8每次尝试将哈希转换为 JSON 字符串时,我都会得到一个。我尝试了使用[.encode | .force_encoding](["UTF-8" | "ASCII-8BIT" ]),链接.encode.force_encoding向后,切换参数,但似乎没有任何效果,所以我发现了这样的错误:

begin
  menu.to_json
rescue Encoding::UndefinedConversionError
  puts $!.error_char.dump
  p $!.error_char.encoding
end

其中 menu 是续集的 dataset.to_hash,内容来自 MySQL 数据库,utf8_general_ci 编码并返回:

"\xC2"

<#Encoding:ASCII-8BIT>

无论我使用什么.encode,编码都不会改变。.force_encoding我什至试图在.gsub!(/\\\xC2/)没有运气的情况下更换字符串。

有任何想法吗?

4

5 回答 5

89
menu.to_s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')

这工作得很好,我不得不替换一些额外的字符,但没有更多的错误。

于 2013-01-03T06:21:26.817 回答
21

你对“\xC2”有什么期望?大概是一个Â

使用 ASCII-8BIT 你有二进制数据,而 ruby​​ 无法决定应该是什么。

您必须首先使用 设置编码force_encoding

您可以尝试以下代码:

Encoding.list.each{|enc|
  begin
    print "%-10s\t" % [enc]
    print "\t\xC2".force_encoding(enc)
    print "\t\xC2".force_encoding(enc).encode('utf-8')
  rescue => err
    print "\t#{err}"
  end
  print "\n"
}

结果是“\xC2”的不同编码中的可能值。

结果可能取决于您的输出格式,但我认为您可以很好地猜测您拥有哪种编码。

当您定义所需的编码(可能是 cp1251)时,您可以

menu.force_encoding('cp1252').to_json

另见 Kashyaps 评论。

于 2012-10-22T09:31:33.777 回答
12

如果你不在乎失去奇怪的角色,你可以把它们吹走:

str.force_encoding("ASCII-8BIT").encode('UTF-8', undef: :replace, replace: '')
于 2012-12-30T21:11:20.960 回答
10

您自动接受的解决方案不起作用,实际上没有错误,但它不是 JSON。

我使用 oj gem 解决了这个问题,它现在可以找到了。它也比标准 JSON 库更快。

写作:

   menu_json = Oj.dump menu

阅读 :

   menu2 = Oj.load menu_json

https://github.com/ohler55/oj了解更多详情。我希望它会有所帮助。

于 2013-09-20T15:47:57.430 回答
1

如果您知道要替换哪些字符, :fallback 选项会很有用

"Text ".encode("ASCII", "UTF-8", fallback: {"" => ":)"})
#=> hello :)

来自文档:

通过给定对象设置未定义字符的替换字符串。对象应该是 Hash、Proc、Method 或具有 [] 方法的对象。它的键是在当前转码器的源编码中编码的未定义字符。它的值可以是任何编码,直到它可以转换为转码器的目标编码。

于 2020-01-29T12:38:33.450 回答