2011-02-03 43 views
9

我需要在Ruby中解析某些无效的JSON。如何使用ActiveSupport 3解析无效的JSON(Rails)

喜欢的东西:

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

这个无效的json来自哪里?一个休息API或一些文件?最好是修复json,接受无效json的解析器不好,我很高兴他们现在正在使用Yajl。 – 2011-02-03 19:51:55

+0

是的,它是一个API。是的,它很臭,我必须为此做一个解决方法,但我没有任何接触API的开发人员。 – 2011-02-04 17:17:52

回答

0

像这样的事情?

require 'json' 
json_str = '{name:"Javier"}' 
hash = JSON::parse(json_str.gsub(/{|:"/, {'{'=>'{"', ':"'=>'":"'})) 
2

我会使用一个正则表达式来解决这个无效的JSON:

json_str = '{name:"Javier"}' 
json_str.gsub!(/(['"])?([a-zA-Z0-9_]+)(['"])?:/, '"\2":') 
hash = Yajl::Parser.parse(json_str) 
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'