Perl:将散列引用(例如 Dumper 的输出)格式化为字符串
Perl: Format a hash reference (e.g. output of Dumper) into a String
我有一个包含嵌套 key/value 对的散列引用,散列引用 and/or 数组引用。
我想将 Data::Dumper 的结果模拟成一个字符串,但是:
- 从键中删除 'quotes'。
- 从结构中删除空格(但不是值)
- 奖励:按字母顺序对键进行排序。
- 额外奖励:首先打印 key/value 对,然后是散列引用,然后是数组引用。
例如:
#!/usr/bin/perl -w
use strict;
use warnings;
use Data::Dumper;
my $hash_ref = {
'private' => {
'locked' => 'FALSE',
'allowedAuth' => 'Digest'
},
'profile' => 'Default',
'id' => '123456',
'privacy' => 'FALSE',
'public' => [
{
'allowed' => 'FALSE',
'configured' => {
'profileId' => 'hello world'
},
'isDefault' => 'TRUE',
'maxSessions' => '3'
},
{
'isDefault' => 'FALSE',
'privateId' => 'foo@bar.com',
'maxSessions' => '3',
'allowed' => 'FALSE',
'implicit' => '1',
}
],
'indicator' => 'FALSE'
};
print STDERR Dumper ($hash_ref);
理想情况下,我希望输出为:
my $str = "id=>'123456',indicator=>'FALSE',profile=>'Default',privacy=>'FALSE',private=>{allowedAuth=>'Digest',locked=>'FALSE'},public=>[{allowed=>'FALSE',configured=>{profileId=>'hello world'},isDefault=>'TRUE',maxSessions=>'3'},{allowed=>'FALSE',implicit=>'1',isDefault=>'FALSE',maxSessions=>'3',privateId=>'foo@bar.com'}]";
我试过递归函数;但是,我不确定如何去掉末尾的逗号(尤其是散列引用——对于数组引用,我可以使用索引并检查它是否是最后一个)。另外,排序键似乎太难了。
sub recHash
{
my ($hash_ref) = @_;
my $response = "";
for my $k (keys %$hash_ref) {
my $v = $hash_ref->{$k};
if (ref($v) eq "HASH") {
$response .= "$k=>{" . recHash($v) . "}"; # recurse through the hash references.
}
elsif (ref($v) eq "ARRAY") {
$response .= "$k=>[";
# recurse through the array references.
foreach my $item (@$v) {
$response .= "{".recHash($item)."},";
}
$response .= "],";
return $response;
}
else {
$response .= "$k=>'$v',";
}
}
return $response;
}
print recHash($hash_ref);
我的输出是(当我保留 运行 时我认为这是有缺陷的):
private=>{allowedAuth=>'Digest',locked=>'FALSE',}profile=>'Default',id=>'123456',indicator=>'FALSE',privacy=>'FALSE',public=>[{configured=>{profileId=>'hello world',}maxSessions=>'3',allowed=>'FALSE',isDefault=>'TRUE',},{allowed=>'FALSE',maxSessions=>'3',implicit=>'1',privateId=>'foo@bar.com',isDefault=>'FALSE',},],
您只需按如下方式对键进行排序:
for my $k (sort keys %$hash_ref) {
您在每个 运行 得到不同的输出,因为散列键是以随机顺序访问的。
开箱即用的 $Data::Dumper::Indent
和 $Data::Dumper::Sortkeys
值将帮助您实现大部分目标。
use Data::Dumper;
my $hash_ref = { ... };
$Data::Dumper::Indent = 0;
$Data::Dumper::Sortkeys = sub {
my ($hash) = @_;
my %refval = ('' => -3, 'HASH' => -2, 'ARRAY' => -1);
return [ sort {
# prefer ref(val) "" to "HASH" to "ARRAY" to anything else
$refval{ref $hash->{$a}} <=> $refval{ref $hash->{$b}}
# and then sort lexicographically
|| $a cmp $b
} keys %$hash ];
};
my $rec_hash = Dumper($hash_ref);
$rec_hash =~ s/'(\w+)' => /=>/g;
$rec_hash =~ s/^$VAR1 = //;
print $rec_hash;
结果:
{id=>'123456',indicator=>'FALSE',privacy=>'FALSE',profile=>'Default',
private=>{allowedAuth=>'Digest',locked=>'FALSE'},public=>
[{allowed=>'FALSE',isDefault=>'TRUE',maxSessions=>'3',configured=>
{profileId=>'hello world'}},allowed=>'FALSE',implicit=>'1',
isDefault=>'FALSE',maxSessions=>'3',privateId=>'foo@bar.com'}]};
我有一个包含嵌套 key/value 对的散列引用,散列引用 and/or 数组引用。
我想将 Data::Dumper 的结果模拟成一个字符串,但是:
- 从键中删除 'quotes'。
- 从结构中删除空格(但不是值)
- 奖励:按字母顺序对键进行排序。
- 额外奖励:首先打印 key/value 对,然后是散列引用,然后是数组引用。
例如:
#!/usr/bin/perl -w
use strict;
use warnings;
use Data::Dumper;
my $hash_ref = {
'private' => {
'locked' => 'FALSE',
'allowedAuth' => 'Digest'
},
'profile' => 'Default',
'id' => '123456',
'privacy' => 'FALSE',
'public' => [
{
'allowed' => 'FALSE',
'configured' => {
'profileId' => 'hello world'
},
'isDefault' => 'TRUE',
'maxSessions' => '3'
},
{
'isDefault' => 'FALSE',
'privateId' => 'foo@bar.com',
'maxSessions' => '3',
'allowed' => 'FALSE',
'implicit' => '1',
}
],
'indicator' => 'FALSE'
};
print STDERR Dumper ($hash_ref);
理想情况下,我希望输出为:
my $str = "id=>'123456',indicator=>'FALSE',profile=>'Default',privacy=>'FALSE',private=>{allowedAuth=>'Digest',locked=>'FALSE'},public=>[{allowed=>'FALSE',configured=>{profileId=>'hello world'},isDefault=>'TRUE',maxSessions=>'3'},{allowed=>'FALSE',implicit=>'1',isDefault=>'FALSE',maxSessions=>'3',privateId=>'foo@bar.com'}]";
我试过递归函数;但是,我不确定如何去掉末尾的逗号(尤其是散列引用——对于数组引用,我可以使用索引并检查它是否是最后一个)。另外,排序键似乎太难了。
sub recHash
{
my ($hash_ref) = @_;
my $response = "";
for my $k (keys %$hash_ref) {
my $v = $hash_ref->{$k};
if (ref($v) eq "HASH") {
$response .= "$k=>{" . recHash($v) . "}"; # recurse through the hash references.
}
elsif (ref($v) eq "ARRAY") {
$response .= "$k=>[";
# recurse through the array references.
foreach my $item (@$v) {
$response .= "{".recHash($item)."},";
}
$response .= "],";
return $response;
}
else {
$response .= "$k=>'$v',";
}
}
return $response;
}
print recHash($hash_ref);
我的输出是(当我保留 运行 时我认为这是有缺陷的):
private=>{allowedAuth=>'Digest',locked=>'FALSE',}profile=>'Default',id=>'123456',indicator=>'FALSE',privacy=>'FALSE',public=>[{configured=>{profileId=>'hello world',}maxSessions=>'3',allowed=>'FALSE',isDefault=>'TRUE',},{allowed=>'FALSE',maxSessions=>'3',implicit=>'1',privateId=>'foo@bar.com',isDefault=>'FALSE',},],
您只需按如下方式对键进行排序:
for my $k (sort keys %$hash_ref) {
您在每个 运行 得到不同的输出,因为散列键是以随机顺序访问的。
开箱即用的 $Data::Dumper::Indent
和 $Data::Dumper::Sortkeys
值将帮助您实现大部分目标。
use Data::Dumper;
my $hash_ref = { ... };
$Data::Dumper::Indent = 0;
$Data::Dumper::Sortkeys = sub {
my ($hash) = @_;
my %refval = ('' => -3, 'HASH' => -2, 'ARRAY' => -1);
return [ sort {
# prefer ref(val) "" to "HASH" to "ARRAY" to anything else
$refval{ref $hash->{$a}} <=> $refval{ref $hash->{$b}}
# and then sort lexicographically
|| $a cmp $b
} keys %$hash ];
};
my $rec_hash = Dumper($hash_ref);
$rec_hash =~ s/'(\w+)' => /=>/g;
$rec_hash =~ s/^$VAR1 = //;
print $rec_hash;
结果:
{id=>'123456',indicator=>'FALSE',privacy=>'FALSE',profile=>'Default',
private=>{allowedAuth=>'Digest',locked=>'FALSE'},public=>
[{allowed=>'FALSE',isDefault=>'TRUE',maxSessions=>'3',configured=>
{profileId=>'hello world'}},allowed=>'FALSE',implicit=>'1',
isDefault=>'FALSE',maxSessions=>'3',privateId=>'foo@bar.com'}]};