0
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 ) {
    @layer2 = $_->{$decoded->{'arms'} };
   foreach( @layer2 ) {
     print $_->{$decoded->{'hands'}} . "\n";
   }
}

我希望打印输出是:fingers 我的最终结果目标是,“如果 abs 是六块包,那么将词指打印到文件中。” 当然,我正在尝试从大型 JSON 大规模地执行此操作。

4

1 回答 1

1

如果你打开了use strictand use warnings,你应该总是这样做,你会得到一堆关于未声明变量的致命错误。让我们先解决这些问题:

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";
   }
}

现在,至少代码将在use strict. 但它会发出一堆警告:

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.

这些警告是有用的信息!多么有用的工具use warnings啊!

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

第 21 行是:

my @layer2 = $_->{$decoded->{'arms'} };

在此循环中,$_设置为外部数组 ( @{ $decoded->{body} }) 的每个元素。该数组的每个元素都是一个哈希引用。您正在做的是尝试使用散列arms第一级中的键作为数组中元素指向的散列的键。这些散列中不存在该键,这就是为什么您会收到有关未初始化值的警告的原因。

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

my @layer2 = @{ $_->{arms} };

现在第三层更复杂了;它是一个以冒号分隔的字符串数组,而不是一个哈希数组。在那个循环中,我们可以丢弃我们不想要的字符串,直到我们找到hands

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";
    }
}

输出:

fingers

有关在 Perl 中处理复杂结构的更多信息,请参阅以下内容:

阅读它们,再次阅读它们,然后编写代码。然后再读一遍。

于 2013-09-12T06:15:38.187 回答