如何解析这个JSON对象/字符串?

时间:2014-07-28 15:08:15

标签: json perl amazon-web-services

我正在尝试解析写成@ http://a0.awsstatic.com/pricing/1/ec2/sles-od.min.js

的JSON

以下是上面链接的快速摘录:

{vers:0.01,config:{rate:"perhr",valueColumns:["vCPU","ECU","memoryGiB","storageGB","sles"],currencies:["USD"],regions:[{region:"us-east",instanceTypes:[{type:"generalCurrentGen",sizes:[{size:"t2.micro",vCPU:"1",ECU:"variable",
...
...
...
...

请访问上述链接以查看完整的JSON。

如上所示,上述JSON的 keys 都没有双引号

这导致格式错误的JSON字符串,我的JSON解析器失败了。我也尝试将这个JSON放在http://www.jsoneditoronline.org/中,它也失败了。

现在,这是亚马逊用于显示其EC2实例的各种价格的链接。所以我想我在这里错过了一些东西。我的谷歌搜索让我相信上面的事情不是JSON而是JSONP ..我不明白那是什么。

你能帮我理解如何解析这个JSON吗?顺便说一句,我正在使用JSON Module进行此项工作。

某些背景:

Amazon Web Services没有用于以编程方式获取定价信息的API。因此,我正在解析这些链接,这是亚马逊在显示定价信息时所做的事情here。此外,我不是来自编程空间,perl就是我所知道的。

2 个答案:

答案 0 :(得分:3)

就像你说的那样JSONP或“JSON with padding”无法被json解析器解析,因为它不是json(它是一种不同的格式)。但它实际上是带有前缀(填充)的json

填充通常是包装json的回调函数的名称。

在这种情况下,它的默认回调名称'回调',我们可以通过使用正则表达式来捕获被'callback()'包裹的json,这样可以做一些最黑客的方式

s/callback\((.*)\);$/$1/s;

另外,如果您想使用JSON库,则可以启用allow_barekey,这意味着您不需要围绕这些键的引号。

以下是我的工作代码。我使用LWP::Simple获取给定内容,Data::Dump打印隔离数据结构。

use strict;
use warnings;

use LWP::Simple;
use JSON;

my $jsonp = get("http://a0.awsstatic.com/pricing/1/ec2/sles-od.min.js")
    or die "Couldn't get url";

( my $json = $jsonp ) =~ s/callback\((.*)\);$/$1/s; #grap the json from $jsonp and store in $json variable
my $hash = JSON->new->allow_barekey->decode ( $json );

use Data::Dump;
dd $hash;

输出:

{
  config => {
              currencies => ["USD"],
              rate => "perhr",
              regions => [
                {
                  instanceTypes => [
                    {
                      sizes => [
                                 {
                                   ECU => "variable",
                                   memoryGiB => 1,
                                   size => "t2.micro",
                                   storageGB => "ebsonly",
                                   valueColumns => [{ name => "os", prices => { USD => 0.023 } }],
                                   vCPU => 1,
                                 },
                                 {
                                   ECU => "variable",
                                   memoryGiB => 2,
                                   size => "t2.small",
                                   storageGB => "ebsonly",
                                   valueColumns => [{ name => "os", prices => { USD => 0.056 } }],
                                   vCPU => 1,
                                 },
                                 {
                                   ECU => "variable",
                                   memoryGiB => 4,
                                   size => "t2.medium",
                                   storageGB => "ebsonly",
                                   valueColumns => [{ name => "os", prices => { USD => 0.152 } }],
                                   vCPU => 2,
                                 },
                                 {
                                   ECU => 3,
                                   memoryGiB => 3.75,
                                   size => "m3.medium",
                                   storageGB => "1 x 4 SSD",
                                   valueColumns => [{ name => "os", prices => { USD => "0.170" } }],
                                   vCPU => 1,
                                 },
....

答案 1 :(得分:2)

如上面的评论所述,它不是JSON所以它不能被JSON解析器解析...但对于 quick& (非常)脏工作,你可以尝试JSON::DWIW模块。

下一个代码:

use 5.014;
use warnings;
use WWW::Mechanize;
use Data::Dump;

use JSON::DWIW;

my $mech = WWW::Mechanize->new();
my $jsonstr = $mech->get('http://a0.awsstatic.com/pricing/1/ec2/sles-od.min.js')->content;
($jsonstr) = $jsonstr =~ /callback\((.*)\)/s;

my $json_obj = JSON::DWIW->new;
my $data = $json_obj->from_json( $jsonstr );
dd $data;

打印一个可能的结构,例如:

{
  config => {
              currencies => ["USD"],
              rate => "perhr",
              regions => [
                {
                  instanceTypes => [
                    {
                      sizes => [
                                 {
                                   ECU => "variable",
                                   memoryGiB => 1,
                                   size => "t2.micro",
                                   storageGB => "ebsonly",
                                   valueColumns => [{ name => "os", prices => { USD => 0.023 } }],
                                   vCPU => 1,
                                 },
                                 {