我正在使用谷歌的定义URL,它返回一个包含JSONP数据的响应流(见下文).
GET http://www.google.com/dictionary/json?callback=a&sl=en&tl=en&q=epitome
响应如下:
a({"query": "epitome", ...}, 200, null)
在解析JSON之前,我必须去掉回调参数; 这意味着消除之前,首先一切{
,一切都在最后}
.
我有正则表达式去除回调参数,但在使用HTTParty请求时遇到问题.
正则表达式以剥离填充
^\w+\(|[^}]+$
我尝试过使用以下内容,但收到错误.
base_url = "http://www.google.com/dictionary/json?callback=a&sl=en&tl=en&q=" word = "epitome" request = HTTParty.get("#{base_url}#{word}").gsub(/^\w+\(|[^}]+$/)
HTTParty自动尝试解析忽略该gsub!
方法的数据; 所以我不确定如何在HTTParty尝试解析返回的数据之前添加regexp去除回调参数.
关于这个的任何提示?
使用自定义解析器.在这个例子中,我使用子字符串去除填充,但如果您愿意,可以使用正则表达式:
require 'httparty' class JsonpParser < HTTParty::Parser SupportedFormats = {"text/javascript" => :jsonp} def jsonp JSON.load(body[2..-11], nil) end end class Dictionary include HTTParty parser JsonpParser def self.define(word) get "http://www.google.com/dictionary/json?callback=a&sl=en&tl=en&q=#{word}" end end Dictionary.define 'epitome'
这很容易做到,除了常规的Ruby以及它附带的JSON和OpenURI类之外什么都没有.考虑一下:
require 'open-uri' require 'json' URL = 'http://www.google.com/dictionary/json?callback=a&sl=en&tl=en&q=epitome' jsonp = open(URL).read
此时,jsonp
包含来自Google API的响应.你想要的部分用花括号包裹{...}
.
正则表达式是贪婪的,并且会吞噬它们所能做的一切.通常这是一个问题,但在这种情况下它是好的.一个简单的模式/{.+}/
将找到从第一个{
到最后一个的所有内容}
,即JSON有效负载,此时,您已准备好解析:
payload = jsonp[/{.+}/] # => "{\"query\":\"epitome\",\"sourceLanguage\":\"en\",\"targetLanguage\":\"en\",\"primaries\":[{\"type\":\"headword\",\"terms\":[{\"type\":\"text\",\"text\":\"e·pit·o·me\",\"language\":\"en\",\"labels\":[{\"text\":\"Noun\",\"title\":\"Part-of-speech\"}]},{\"type\":\"phonetic\",\"text\":\"/i?pit?m?/\",\"language\":\"und\"},{\"type\":\"sound\",\"text\":\"http://www.gstatic.com/dictionary/static/sounds/de/0/epitome.mp3\",\"language\":\"und\"}],\"entries\":[{\"type\":\"related\",\"terms\":[{\"type\":\"text\",\"text\":\"epitomes\",\"language\":\"und\",\"labels\":[{\"text\":\"plural\"}]}]},{\"type\":\"meaning\",\"terms\":[{\"type\":\"text\",\"text\":\"A person or thing that is a perfect example of a particular quality or type\",\"language\":\"en\"}],\"entries\":[{\"type\":\"example\",\"terms\":[{\"type\":\"text\",\"text\":\"she looked the \\x3cem\\x3eepitome\\x3c/em\\x3e of elegance and good taste\",\"language\":\"en\"}]}]},{\"type\":\"meaning\",\"terms\":[{\"type\":\"text\",\"text\":\"A summary of a written work; an abstract\",\"language\":\"en\"}]},{\"type\":\"meaning\",\"terms\":[{\"type\":\"text\",\"text\":\"A thing representing something else in miniature\",\"language\":\"en\"}]}]}]}"
解析:
data = JSON.parse(payload) # => {"query"=>"epitome", # "sourceLanguage"=>"en", # "targetLanguage"=>"en", # "primaries"=> # [{"type"=>"headword", # "terms"=> # [{"type"=>"text", # "text"=>"e·pit·o·me", # "language"=>"en", # "labels"=>[{"text"=>"Noun", "title"=>"Part-of-speech"}]}, # {"type"=>"phonetic", "text"=>"/i?pit?m?/", "language"=>"und"}, # {"type"=>"sound", # "text"=> # "http://www.gstatic.com/dictionary/static/sounds/de/0/epitome.mp3", # "language"=>"und"}], # "entries"=> # [{"type"=>"related", # "terms"=> # [{"type"=>"text", # "text"=>"epitomes", # "language"=>"und", # "labels"=>[{"text"=>"plural"}]}]}, # {"type"=>"meaning", # "terms"=> # [{"type"=>"text", # "text"=> # "A person or thing that is a perfect example of a particular quality or type", # "language"=>"en"}], # "entries"=> # [{"type"=>"example", # "terms"=> # [{"type"=>"text", # "text"=> # "she looked the x3cemx3eepitomex3c/emx3e of elegance and good taste", # "language"=>"en"}]}]}, # {"type"=>"meaning", # "terms"=> # [{"type"=>"text", # "text"=>"A summary of a written work; an abstract", # "language"=>"en"}]}, # {"type"=>"meaning", # "terms"=> # [{"type"=>"text", # "text"=>"A thing representing something else in miniature", # "language"=>"en"}]}]}]}
现在你已经有了一个很好的ol'Ruby hash,你可以正常访问:
data['query'] # => "epitome"
总结一下:
require 'open-uri' require 'json' URL = 'http://www.google.com/dictionary/json?callback=a&sl=en&tl=en&q=epitome' data = JSON.parse(open(URL).read[/{.+}/]) data['query'] # => "epitome" data['primaries'].size # => 1
而且,它也适用于常规JSON结果,因此您无需执行任何特殊操作即可.