Perl:将哈希引用(例如Dumper的输出)格式化为String

时间:2015-07-12 18:23:51

标签: arrays perl hash perl-data-structures

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

我想将Data :: Dumper的结果模拟成一个字符串,但是:

  1. 从键中删除“引号”。
  2. 从结构中删除空格(但不是值)
  3. 奖励:按字母顺序对键进行排序。
  4. Bonus Bonus:首先打印键/值对,然后是哈希引用,然后是数组引用。
  5. 例如:

    CREATE TABLE `client` (
      `client_code` INT UNSIGNED NOT NULL AUTO_INCREMENT,
      `company_name` VARCHAR(255) NOT NULL,
      PRIMARY KEY `client_code` (`client_code`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;
    
    CREATE TABLE `employee` (
      `client_code` INT UNSIGNED NOT NULL,
      `emp_mobile` VARCHAR(255) NOT NULL,
      `emp_email` VARCHAR(255) NOT NULL,
      `emp_first_name` VARCHAR(255) NOT NULL,
      `emp_last_name` VARCHAR(255) NOT NULL,
      KEY `client_code` (`client_code`),
      CONSTRAINT `employee_ibfk_1` FOREIGN KEY (`client_code`) REFERENCES `client` (`client_code`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;
    

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

    #!/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);
    

2 个答案:

答案 0 :(得分:1)

开箱即用的$Data::Dumper::Sortkeysuse 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; 值可以帮助您完成大部分工作。

{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}}

答案 1 :(得分:-1)

您只需按如下方式对键进行排序:

for my $k (sort keys %$hash_ref) {

由于以随机顺序访问哈希键,因此每次运行时都会得到不同的输出。