据我所知,在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"}
>>
(我尝试使用正则表达式在解析之前添加引号,但无法使其完全正常工作)。
答案 0 :(得分:16)
如果数据形成得非常好,那么一个简单的正则表达式可能会这样做:
irb(main):009:0> '{name:"hello", age:"23"}'.gsub(/([a-z]+):/, '"\1":')
=> "{\"name\":\"hello\", \"age\":\"23\"}"
答案 1 :(得分:9)
我在第三方数据Feed中遇到了同样的问题,但我的返回更复杂的类似JSON的响应,gsub解决方案无法处理。经过一些研究后,看来这些数据源实际上是JavaScript对象文字,不需要引用键。
为了解决这个问题,我添加了execjs gem并安装了node.js(therubyracer gem也可能会起作用)。完成后,以下内容返回正确解析的ruby散列。
ExecJS.eval('{name:"hello", age:"23"}')
=> {"name"=>"hello", "age"=>"23"}
答案 2 :(得分:7)
有趣的是,您的示例是有效的ruby 1.9 Hash语法。如果您的数据真的如此简单(键名中没有空格或其他特殊字符),并且您可以在安全的上下文中处理它,那么您可以eval
它。
irb(main):001:0> eval '{name:"hello", age:"23"}'
=> {:name=>"hello", :age=>"23"}
这会将符号作为键,因此如果需要将它们转换为字符串,则需要进行后处理:
irb(main):002:0> eval('{name:"hello", age:"23"}').reduce({}) {|h,(k,v)| h[k.to_s] = v; h}
=> {"name"=>"hello", "age"=>"23"}
答案 3 :(得分:2)
gsub(/(\w+)\s*:/, '"\1":')
比
工作得更好gsub(/([a-z]+):/, '"\1":')
如果它有空格或大写字母,则失败。
答案 4 :(得分:1)
(回答我自己的问题)floyd发布的片段与我尝试的类似 - 它失败了,因为我的一些字符串包含冒号。但我坚持并找到了解决方案:
gsub(/([\{|\,}])\s*([a-zA-Z]+):/, '\1 "\2":')
答案 5 :(得分:0)
这就是我必须解决的问题:
JSON.parse(broken_json_string.gsub(/'([^']+)':/, '"\1":'))
上面的一些假设键只包含字母;我们中的一些包含下划线,空格等。更容易说“任何不是单引号的字符”(在我们的例子中,所有键都包含在单引号中)。