2011-02-03 42 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'