首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Perl:将哈希引用(例如Dumper的输出)格式化为字符串

Perl:将哈希引用(例如Dumper的输出)格式化为字符串
EN

Stack Overflow用户
提问于 2015-07-12 18:23:51
回答 2查看 1.2K关注 0票数 0

我有一个哈希引用,它包含嵌套的键/值对、哈希引用和/或数组引用。

我希望将数据::Dumper的结果模拟为字符串,但使用:

  1. 从键中删除“引号”。
  2. 从结构中删除空白(但不删除值)
  3. 奖励:按字母顺序排序键。
  4. 额外奖励:首先打印键/值对,然后是散列引用,然后是数组引用。

例如:

代码语言:javascript
运行
复制
#!/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);

理想情况下,我希望输出如下:

代码语言:javascript
运行
复制
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'}]";

我尝试了一个递归函数;但是,我不知道如何去掉末尾的逗号(特别是散列引用-对于数组引用,我可以使用一个索引并检查它是否是最后一个索引)。另外,分类键似乎太难了。

代码语言:javascript
运行
复制
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);

我的输出是(当我继续运行它时,我认为它是有缺陷的):

代码语言:javascript
运行
复制
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',},],
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-12 18:48:27

开箱即用的$Data::Dumper::Indent$Data::Dumper::Sortkeys值将使您获得大部分的方式。

代码语言:javascript
运行
复制
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+)' => /$1=>/g;
$rec_hash =~ s/^\$VAR1 = //;
print $rec_hash;

结果:

代码语言:javascript
运行
复制
{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'}]};
票数 1
EN

Stack Overflow用户

发布于 2015-07-12 18:45:12

您只需按以下方式对密钥进行排序:

代码语言:javascript
运行
复制
for my $k (sort keys %$hash_ref) {

每次运行时,您都会得到不同的输出,因为散列键是按随机顺序访问的。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31371086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档