【问题标题】:Encode Perl's Data::Dumper to JSON将 Perl 的 Data::Dumper 编码为 JSON
【发布时间】:2016-02-29 04:54:09
【问题描述】:

我有一个 Perl Data::Dumper 文件 (data.txt),其中包含两个需要转换为 JSON 的数组。

这是我的 data.txt:

$stats = {
  'oldtime' => '04',
  'parsedlines' => 8,
  'day_lines' => [
    undef,
    8
  ],
  'actions' => {
    'microbe' => 1
  },
  'lastnick' => 'Sky',
  'words' => {
    'Sky' => 1,
    'microbe' => 9
  },
  'times' => {
    '04' => 8
  },
  'totallines' => 8,
  'word_times' => {
    'microbe' => [
      9
    ],
    'Sky' => [
      1
    ]
  },
  'lastvisited' => {
    'microbe' => 1,
    'Parts:' => 1,
    'Sky' => 1
  },
  'line_times' => {
    'microbe' => [
      3
    ],
    'Sky' => [
      1
    ]
  },
  'lengths' => {
    'microbe' => 36,
    'Sky' => 11
  },
  'lastnormal' => '[04:35:01] <Sky> ;algkagkaga
',
  'day_times' => [
    undef,
    [
      8,
      0,
      0,
      0
    ]
  ],
  'days' => 1,
  'joins' => {
    'microbe' => 1,
    'Sky' => 1
  },
  'monocount' => 0,
  'lines' => {
    'Sky' => 1,
    'microbe' => 3
  }
};
$lines = {
  'actionlines' => {
    'microbe' => [
      '[04:33:53] * microbe is doing just a test
'
    ]
  },
  'sayings' => {
    'Sky' => [
      ';algkagkaga'
    ],
    'microbe' => [
      'Hello'
    ]
  }
};

如您所见,有 2 个数组:$stats 和 $lines。
我想将它们转换为 JSON。
这里有人(Borodin)提出了一个可行的解决方案,但它只输出第二个数组($lines)。这是他的解决方案:

use strict;
use warnings qw/ all FATAL /;

use JSON;

print encode_json( do 'data.txt' or die $! ), "\n";  

但这是它的输出:

{

    "actionlines":{
        "microbe":[
            "[04:33:53] * microbe is doing just a test\n"
        ]
    },
    "sayings":{
        "microbe":[
            "Hello"
        ],
        "Sky":[
            ";algkagkaga"
        ]
    }

}

所以它只输出 $lines 数组...知道我可以做些什么来让它工作吗?

【问题讨论】:

标签: arrays json perl


【解决方案1】:

要单独访问数据文件中的哈希引用,您需要在执行do之前使用our声明它们

这样

use strict;
use warnings 'all';

use JSON;

our ( $stats, $lines );

do 'data.txt' or die $!;

print encode_json( $stats ), "\n";
print encode_json( $lines ), "\n";

输出

{"day_times":[null,[8,0,0,0]],"actions":{"microbe":1},"lines":{"microbe":3,"Sky":1},"days":1,"lastnick":"Sky","oldtime":"04","words":{"Sky":1,"microbe":9},"lastnormal":"[04:35:01] <Sky> ;algkagkaga\n","times":{"04":8},"joins":{"Sky":1,"microbe":1},"totallines":8,"monocount":0,"lastvisited":{"Parts:":1,"microbe":1,"Sky":1},"word_times":{"microbe":[9],"Sky":[1]},"line_times":{"Sky":[1],"microbe":[3]},"parsedlines":8,"lengths":{"Sky":11,"microbe":36},"day_lines":[null,8]}
{"sayings":{"microbe":["Hello"],"Sky":[";algkagkaga"]},"actionlines":{"microbe":["[04:33:53] * microbe is doing just a test\n"]}}

【讨论】:

    【解决方案2】:

    您没有两个数组。你有两个哈希值。

    您的代码调用do 并将其返回值作为encode_json() 的唯一参数传递。来自perldoc:

    如果文件编译成功,则返回最后一个表达式的值。

    这意味着您将data.txt 文件中最后一个表达式的值作为参数传递给encode_json()。该值是分配给$lines 的哈希值。

    可能的解决方案:

    1. 在生成 data.txt 时,将两个哈希组合成一个哈希数组。

    2. 在调用encode_json() 之前执行data.txt 文件,忽略它的返回值。然后,通过包限定名称引用这两个变量,将它们组合成一个匿名数组。因为它们的声明前面没有my,并且它们是在main 包内隐式声明的,所以包将是main。下面是它的外观:


    require('data.txt');
    print encode_json([$main::stats,$main::lines]), "\n";
    

    【讨论】:

    • require 用于带有 package 语句的文件。 OP 使用do 更合适。
    猜你喜欢
    • 1970-01-01
    • 2011-06-26
    • 2014-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多