如何在Perl中解析3D JSON数组?

如何在Perl中解析3D JSON数组?,perl,hash,multidimensional-array,json,Perl,Hash,Multidimensional Array,Json,我正在尝试这个,但它不起作用: my $test = '{ "name":"Tony", "body":[ { "arms":["hands:fingers", "muscles:biceps"], "stomach":["abs:sixpack", "noabs:onepack"] }, { "arms":["fingers:nails", "knuck

我正在尝试这个,但它不起作用:

my $test = '{
   "name":"Tony",
   "body":[ {
             "arms":["hands:fingers", "muscles:biceps"],
             "stomach":["abs:sixpack", "noabs:onepack"]
             },
             {
             "arms":["fingers:nails", "knuckles:sharp"],
             "stomach":["abs:gut", "noabs:liquor"]
          }]
}';
我希望打印输出是:fingers
我的最终结果目标是,“如果abs是一个六块的,那么将单词fingers打印到一个文件中。”当然,我正在尝试从一个大型JSON大规模地执行此操作。

如果您启用了
使用严格的
使用警告
,您应该经常这样做,那么您将得到一堆关于未声明变量的致命错误。让我们先解决这些问题:

my $decoded = decode_json($test);
my @layer1 = @{ $decoded->{'body'} };
foreach ( @layer1 ) {
    @layer2 = $_->{$decoded->{'arms'} };
   foreach( @layer2 ) {
     print $_->{$decoded->{'hands'}} . "\n";
   }
}
现在,至少代码将在
使用strict
下编译。但它发出了一系列警告:

use strict;
use warnings;

use JSON;

my $test='{
   "name":"Tony",
   "body":[ {
             "arms":["hands:fingers", "muscles:biceps"],
             "stomach":["abs:sixpack", "noabs:onepack"]
             },
             {
             "arms":["fingers:nails", "knuckles:sharp"],
             "stomach":["abs:gut", "noabs:liquor"]
          }]
}';

my $decoded = decode_json($test);
my @layer1 = @{ $decoded->{'body'} };
foreach ( @layer1 ) {
   my @layer2 = $_->{$decoded->{'arms'} };
   foreach( @layer2 ) {
     print $_->{$decoded->{'hands'}} . "\n";
   }
}
这些警告是有用的信息!多么有用的工具
使用警告

让我们来看第一个:在js.pl第21行的hash元素中使用未初始化的值

第21行是:

Use of uninitialized value in hash element at js.pl line 21.
Use of uninitialized value in hash element at js.pl line 23.
Use of uninitialized value in concatenation (.) or string at js.pl line 23.

Use of uninitialized value in hash element at js.pl line 21.
Use of uninitialized value in hash element at js.pl line 23.
Use of uninitialized value in concatenation (.) or string at js.pl line 23.
在这个循环中,
$\
被设置为外部数组的每个元素(
@{$decoded->{body}
)。该数组的每个元素都是散列引用。您所做的是尝试使用散列第一级中的键
arms
,作为数组中元素指向的散列的键。该键在这些散列中不存在,这就是为什么会出现关于未初始化值的警告

为了得到我们想要的,我们只需要

my @layer2 = $_->{$decoded->{'arms'} };
现在第三层更复杂了;它是由冒号分隔的字符串组成的数组,而不是哈希数组。在这个循环中,我们可以扔掉我们不想要的字符串,直到找到
hands

my @layer2 = @{ $_->{arms} };
以下是固定脚本:

foreach( @layer2 ) { 
    next unless /^hands:/;
    my ( $thing, $other_thing ) = split /:/, $_;
    print $other_thing, "\n";
}
输出:

use strict;
use warnings;

use JSON;

my $test='{
   "name":"Tony",
   "body":[ {
             "arms":["hands:fingers", "muscles:biceps"],
             "stomach":["abs:sixpack", "noabs:onepack"]
             },
             {
             "arms":["fingers:nails", "knuckles:sharp"],
             "stomach":["abs:gut", "noabs:liquor"]
          }]
}';

my $decoded = decode_json($test);
my @layer1 = @{ $decoded->{'body'} };
foreach ( @layer1 ) {
    my @layer2 = @{ $_->{arms} };
    foreach( @layer2 ) {
        next unless /^hands:/;
        my ( $thing, $other_thing ) = split /:/, $_;
        print $other_thing, "\n";
    }
}
有关在Perl中使用复杂结构的更多信息,请参见以下内容:


读一遍,再读一遍,然后写代码。然后再读一遍。

你能在这里显示$decoded
use strict的结果吗;使用警告
在内部循环中使用
$decoded
,但此时应仅处理
$decoded
的子元素。此外,“arms”的值看起来不是散列,因此您不能编写类似
$…->{'arms'}
的内容。
fingers