据我所知,在JSON中,键应该用双引号括起来.但是,我正在使用一个不引用它们的数据源,这导致Ruby JSON解析器引发错误.有没有办法执行'非严格'解析?
例:
>> JSON.parse('{name:"hello", age:"23"}')
JSON::ParserError: 618: unexpected token at '{name:"hello", age:"23"}'
from /Library/Ruby/Gems/1.8/gems/json-1.1.7/lib/json/common.rb:122:in `parse'
from /Library/Ruby/Gems/1.8/gems/json-1.1.7/lib/json/common.rb:122:in `parse'
from (irb):5
>> JSON.parse('{"name":"hello", "age":"23"}')
=> {"name"=>"hello", "age"=>"23"}
>>
Run Code Online (Sandbox Code Playgroud)
(我尝试使用正则表达式在解析之前添加引号,但无法使其完全正常工作).
tfw*_*ght 16
如果数据非常好,那么一个简单的正则表达式可能会这样做:
irb(main):009:0> '{name:"hello", age:"23"}'.gsub(/([a-z]+):/, '"\1":')
=> "{\"name\":\"hello\", \"age\":\"23\"}"
Run Code Online (Sandbox Code Playgroud)
我在第三方数据源中遇到了同样的问题,但是我的返回更复杂的类JSON响应,而gsub解决方案无法处理.经过一些研究后,看来这些数据源实际上是JavaScript对象文字,不需要引用键.
为了解决这个问题,我添加了execjs gem并安装了node.js(therubyracer gem也可能会起作用).完成后,以下内容返回正确解析的ruby哈希值.
ExecJS.eval('{name:"hello", age:"23"}')
=> {"name"=>"hello", "age"=>"23"}
Run Code Online (Sandbox Code Playgroud)
有趣的是,您的示例是有效的ruby 1.9 Hash语法.如果您的数据真的如此简单(键名中没有空格或其他特殊字符),并且您可以在安全的上下文中处理它,那么您就可以eval
了.
irb(main):001:0> eval '{name:"hello", age:"23"}'
=> {:name=>"hello", :age=>"23"}
Run Code Online (Sandbox Code Playgroud)
这会将符号作为键,因此如果需要将它们转换为字符串,则需要进行后处理:
irb(main):002:0> eval('{name:"hello", age:"23"}').reduce({}) {|h,(k,v)| h[k.to_s] = v; h}
=> {"name"=>"hello", "age"=>"23"}
Run Code Online (Sandbox Code Playgroud)