Ruby to_json 出现错误“非法/格式错误的 utf-8”问题
Posted
技术标签:
【中文标题】Ruby to_json 出现错误“非法/格式错误的 utf-8”问题【英文标题】:Ruby to_json issue with error "illegal/malformed utf-8" 【发布时间】:2013-08-06 16:39:03 【问题描述】:尝试将散列转换为 json 字符串时出现错误 JSON::GeneratorError: source sequence is illegal/malformed utf-8
。我想知道这是否与编码有关,我怎样才能让 to_json 按原样对待 \xAE?
$ irb
2.0.0-p247 :001 > require 'json'
=> true
2.0.0-p247 :002 > a = "description"=> "iPhone\xAE"
=> "description"=>"iPhone\xAE"
2.0.0-p247 :003 > a.to_json
JSON::GeneratorError: source sequence is illegal/malformed utf-8
from (irb):3:in `to_json'
from (irb):3
from /Users/cchen21/.rvm/rubies/ruby-2.0.0-p247/bin/irb:16:in `<main>'
【问题讨论】:
以防万一您的意思是“按原样处理”,您可以对其进行双重转义: "description"=> "iPhone\\xAE".to_json => "\"description \":\"iPhone\\\\xAE\"" 【参考方案1】:\xAE
不是 UTF-8 中的有效字符,您必须改用 \u00AE
:
"iPhone\u00AE"
#=> "iPhone®"
或者进行相应的转换:
"iPhone\xAE".force_encoding("ISO-8859-1").encode("UTF-8")
#=> "iPhone®"
【讨论】:
【参考方案2】:Ruby 中的每个字符串都有一个底层编码。根据您的 LANG
和 LC_ALL
环境变量,交互式 shell 可能会以给定的编码执行和解释您的字符串。
$ irb
1.9.3p392 :008 > __ENCODING__
=> #<Encoding:UTF-8>
(忽略我使用的是 Ruby 1.9 而不是 2.0,思路还是一样的)。
__ENCODING__
返回当前源编码。你的可能也会说 UTF-8。
当您在代码中创建文字字符串并使用字节转义符(\xAE
)时,Ruby 会尝试根据字符串编码对其进行解释:
1.9.3p392 :003 > a = "description" => "iPhone\xAE"
=> "description"=>"iPhone\xAE"
1.9.3p392 :004 > a["description"].encoding
=> #<Encoding:UTF-8>
因此,文字字符串末尾的字节 \xAE
将被尝试视为 UTF-8 流字节,但它是无效的。看看我尝试打印时会发生什么:
1.9.3-p392 :001 > puts "iPhone\xAE"
iPhone�
=> nil
您需要提供有效 UTF-8 编码的注册标记字符(使用真实字符,或提供两个 UTF-8 字节):
1.9.3-p392 :002 > a = "description1" => "iPhone®", "description2" => "iPhone\xc2\xae"
=> "description1"=>"iPhone®", "description2"=>"iPhone®"
1.9.3-p392 :005 > a.to_json
=> "\"description1\":\"iPhone®\",\"description2\":\"iPhone®\""
或者,如果您的输入是 ISO-8859-1(拉丁语 1)并且您确定,您可以告诉 Ruby 将您的字符串解释为另一种编码:
1.9.3-p392 :006 > a = "description1" => "iPhone\xAE".force_encoding('ISO-8859-1')
=> "description1"=>"iPhone\xAE"
1.9.3-p392 :007 > a.to_json
=> "\"description1\":\"iPhone®\""
希望对你有帮助。
【讨论】:
非常感谢您的清晰解释。我没有注意到 \xAE 不是 UTF-8 编码而是使用 javascript 转义 (charbase.com/00ae-unicode-registered-sign) 非常感谢。我同意,如果我们不确定输入编码,我们不应该 force_encode 为“ISO-8859-1”。在这种情况下,我通常会从字符串中删除格式错误的字符。以上是关于Ruby to_json 出现错误“非法/格式错误的 utf-8”问题的主要内容,如果未能解决你的问题,请参考以下文章
PayPal IPN:已完成 500 内部服务器 JSON::GeneratorError(源序列非法/格式错误的 utf-8):
何时在 Ruby 的 JSON 库中使用转储与生成与 to_json 以及加载与解析?
ruby 更改Rails 3.2.13和4.0如何在JSONMonkey修补程序ActiveSupport中编码unicode以恢复to_json unicode字符编码。