将配置类似哈希的数据读入perl哈希

时间:2014-06-24 21:04:13

标签: perl hash

我有一个配置文件config.txt,如

{sim}{time}{end}=63.1152e6;
{sim}{output}{times}=[2.592e6,31.5576e6,63.1152e6];
{sim}{fluid}{comps}=[ ['H2O','H_2O'], ['CO2','CO_2'],['NACL','NaCl'] ];

我想把它读成一个perl哈希,

my %h=read_config('config.txt');

我已检出模块Config::Hash,但它没有提供相同的输入文件格式。

1 个答案:

答案 0 :(得分:2)

可以自己滚动。使用Data::Diver来遍历哈希,但也可以手动执行。

use strict;
use warnings;

use Data::Diver qw(DiveVal);

my %hash;

while (<DATA>) {
    chomp;
    my ($key, $val) = split /\s*=\s*/, $_, 2;

    my @keys = $key =~ m/[^{}]+/g;

    my $value = eval $val;
    die "Error in line $., '$val': $@" if $@;

    DiveVal(\%hash, @keys) = $value;
}

use Data::Dump;
dd \%hash;

__DATA__
{sim}{time}{end}=63.1152e6;
{sim}{output}{times}=[2.592e6,31.5576e6,63.1152e6];
{sim}{fluid}{comps}=[ ['H2O','H_2O'], ['CO2','CO_2'],['NACL','NaCl'] ];

输出:

{
  sim => {
           fluid  => { comps => [["H2O", "H_2O"], ["CO2", "CO_2"], ["NACL", "NaCl"]] },
           output => { times => [2592000, 31557600, 63115200] },
           time   => { end => 63115200 },
         },
}

如果你能想出一种不使用eval但不知道你的数据的方法会更好,我无法准确地提出替代方案。

更好的选择,使用JSON或YAML

如果您自己选择数据格式,我建议您使用JSONYAML来保存和加载配置数据。

use strict;
use warnings;

use JSON;

my %config = (
  sim => {
           fluid  => { comps => [["H2O", "H_2O"], ["CO2", "CO_2"], ["NACL", "NaCl"]] },
           output => { times => [2592000, 31557600, 63115200] },
           time   => { end => 63115200 },
         },
);

my $string = encode_json \%config;

## Save the string to a file, and then load below:

my $loaded_config = decode_json $string;

use Data::Dump;
dd $loaded_config;