在没有引用键的情况下解析JSON

And*_*ite 24 ruby json

据我所知,在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)

  • `'{name:"hello",age:"23"}'.gsub(/([\ w] +):/,'"\ 1":')`使它更健壮! (6认同)
  • 如果值是时间戳,则会失败.例如{name:"Hello",time:"12:59:59"} (4认同)

LWC*_*der 9

我在第三方数据源中遇到了同样的问题,但是我的返回更复杂的类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)


gle*_*ald 7

有趣的是,您的示例是有效的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)

  • 这可能非常危险......(例如,如果你从服务器`{a:1}获得; \`rm -rf/\``) (5认同)