我需要在Ruby中解析某些无效的JSON。
类似的东西:
json_str = '{name:"Javier"}'
ActiveSupport::JSON.decode json_str
正如您所看到的,它是无效的,因为没有引用哈希键,它应该是
json_str = '{"name":"Javier"}'
但这不能改变,我必须解析未引用的密钥。
我可以使用ActiveSupport 2.x解析它,但ActiveSupport 3不允许我。它抛出了我:
Yajl::ParseError: lexical error: invalid string in json text.
{name:"Javier"}
(right here) ------^
顺便说一句,它是一个使用一些Rails库的Ruby应用程序,但它不是Rails应用程序
提前致谢
答案 0 :(得分:2)
我会使用正则表达式来修复这个无效的JSON:
json_str = '{name:"Javier"}'
json_str.gsub!(/(['"])?([a-zA-Z0-9_]+)(['"])?:/, '"\2":')
hash = Yajl::Parser.parse(json_str)
答案 1 :(得分:0)
这样的东西?
require 'json'
json_str = '{name:"Javier"}'
hash = JSON::parse( json_str.gsub( /{|:"/, {'{'=>'{"', ':"'=>'":"'} ) )
答案 2 :(得分:0)
这是一个你可以使用的有点强大的正则表达式。它并不完美 - 特别是它在某些极端情况下不起作用,其中值本身包含类似json的文本,但它适用于大多数一般情况:
quoted_json = unquoted_json.gsub(/([{,]\s*)(\w+)(\s*:\s*["\d])/, '\1"\2"\3')
首先,它会查找{
或,
,它们是键名前面的字符的选项(也允许使用\s*
的任意数量的空格)。它将其作为一个组来捕获:
([{,]\s*)
然后它捕获密钥本身,由字母,数字和下划线组成(正则表达式方便地为\w
字符类提供):
(\w+)
最后,它与必须遵循关键名称的内容相匹配;即冒号后跟开始引号(对于字符串值)或数字(对于数值)。还允许额外的空格,并捕获整个组中的整个事物:
(\s*:\s*["\d])
对于每场比赛,它只是将三个部分重新组合在一起,但是在键周围加上引号(所以在捕获组#2周围引用):
'\1"\2"\3'