【问题标题】:Encoding::UndefinedConversionError编码::UndefinedConversionError
【发布时间】:2012-10-11 18:46:12
【问题描述】:

每次我尝试将散列转换为 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 数据库,utf8_general_ci 编码并返回:

"\xC2"

无论我使用什么.encode/.force_encoding,编码都不会改变。我什至尝试替换字符串.gsub!(/\\\xC2/),但没有运气。

有什么想法吗?

【问题讨论】:

  • 1.你试过了吗? menu.force_encoding("ISO-8859-1").encode("UTF-8") 2. 在所有 .rb 文件的顶部添加“# encoding 'utf-8'` 字符串。3. 检查环境设置。终端中的$ echo LC_CTYPE 是什么意思?
  • 第 1 步是否因错误而失败?第 2 步有效吗?对于第 3 步,thegreyblog.blogspot.in/2012/02/… 此链接包含您的程序必须运行的环境设置,以防您想避免该问题。

标签: ruby encoding sinatra sequel


【解决方案1】:
menu.to_s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')

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

【讨论】:

  • 很棒的解决方案 - 解决了我在 SQL Server 中处理奇怪类型的问题。谢谢!
  • 谢谢!它也适用于我,官方 ruby​​ 文档供将来参考here
【解决方案2】:

你对“\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 评论。

【讨论】:

  • 这就是我所做的:'Encoding.list.each{|enc|开始打印 "%-10s\t" % [enc] print menu.to_json.force_encoding(enc) print menu.to_json.force_encoding(enc).encode('utf-8') rescue => err print "\t#{ err}" end print "\n" }´ 这就是我得到的每个结果:´SJIS-KDDI "\xC2" from ASCII-8BIT to UTF-8´
  • 这个所有编码的发现循环非常棒。帮助我解决了我自己在这个问题上的变体。谢谢!
【解决方案3】:

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

str.force_encoding("ASCII-8BIT").encode('UTF-8', undef: :replace, replace: '')

【讨论】:

  • 没用 :( Encoding::UndefinedConversionError at /menu "\xC2" from ASCII-8BIT to UTF-8
  • menu.to_s.encode('UTF-8', {:invalid => :replace, :undef => :replace, :replace => '?'}) -> 这有效! :D
【解决方案4】:

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

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

写作:

   menu_json = Oj.dump menu

阅读:

   menu2 = Oj.load menu_json

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

【讨论】:

  • 问题在于错误,而不是 JSON 部分。因此,我自动接受的答案有效。无论如何,我会支持你提供替代解决方案。
  • 好吧,我同意你的观点,不再有错误,但它不是json字符串。我不知道你的目的是什么,但我需要加载回我的 json,并且我想要一个有效的 JSON 字符串。或者我可能遗漏了您提出的解决方案中的某些内容?
  • 这个问题只是关于错误,我并不是说我的答案是最好的选择,显然它不是为了你的目的,但解决了提出的问题:编码错误。我在问题中提到的 JSON 是出于上下文化目的。
  • 谢谢@gvo!希望其他搜索此错误的人会找到此解决方案...
【解决方案5】:

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

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

来自文档:

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

【讨论】:

    猜你喜欢
    • 2015-02-23
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 2017-10-02
    • 2013-05-01
    • 1970-01-01
    • 2013-08-29
    相关资源
    最近更新 更多