每次尝试将哈希转换为JSON字符串时,我都会收到Encoding::UndefinedConversionError - "\xC2" from ASCII-8BIT to UTF-8
。我尝试使用[.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 DB,utf8_general_ci编码并返回:
“\ XC2”
< #Encoding:ASCII-8BIT>
无论我使用的.encode
/ .force_encoding
是什么,编码都不会改变。我甚至试图在没有运气的情况下替换字符串.gsub!(/\\\xC2/)
。
有什么想法吗?
答案 0 :(得分:73)
menu.to_s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')
这完美无缺,我不得不更换一些额外的字符,但没有更多错误。
答案 1 :(得分:16)
您对“\ 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评论。
答案 2 :(得分:10)
如果你不关心丢失奇怪的角色,你可以把它们吹走:
str.force_encoding("ASCII-8BIT").encode('UTF-8', undef: :replace, replace: '')
答案 3 :(得分:8)
您自动接受的解决方案不起作用,实际上没有错误,但它是 NOT JSON。
我使用oj gem解决了这个问题,它现在可以找到了。它也比标准的JSON库快。
写作:
menu_json = Oj.dump menu
阅读:
menu2 = Oj.load menu_json
https://github.com/ohler55/oj了解更多详情。我希望它会有所帮助。
答案 4 :(得分:1)
:fallback选项可能会有用
"Text ?".encode("ASCII", "UTF-8", fallback: {"?" => ":)"})
#=> hello :)
来自文档:
设置给定对象的替换字符串以定义未定义字符。该对象应该是Hash,Proc,Method或具有[]方法的对象。它的密钥是在当前代码转换器的源编码中编码的未定义字符。它的值可以是任何编码,直到可以将其转换为代码转换器的目标编码为止。