Perl中是否有一个内置的“哈希到字符串”的函数?

19

我想从Python转学Perl,但是在Python中有以下内置的哈希转字符串功能:

>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> str(d)
"{'a': 1, 'c': 3, 'b': 2}"

是否有一个内置的和/或模块,其中包含一个子例程,其输出类似于:

"('a' => 1, 'b' => 2, 'c' => 3)"

奇怪的是,我通过网页搜索 perl "hash to string",却没有找到我需要的内容。谢谢!

6个回答

44
use Data::Dumper;
local $Data::Dumper::Terse = 1;
my $str = Dumper({a => 1, b => 2, c => 3});

31

另请参阅JSON

#!/usr/bin/perl
use warnings; use strict;
use JSON;

my $data = {a => 1, b=> 2, c => 3};

print to_json($data);

这将产生以下结果:

{"c":3,"a":1,"b":2}

4
尽管Data::Dumper似乎是被投票选为答案,但我认为JSON方法同样应该得到赞赏,因为它可以将一个非常简单的哈希转换成字符串。 - Andrew T Finnell
5
尽管原始问题并未提到这一点,但 JSON::to_json 速度很快,所以如果您需要序列化大量数据,这可能比 Data::Dumper 更好。参考链接:http://doppnet.com/2011/03/how-to-gain-24861-performance-boost-in-perl/。 - bigiain
谢谢,我应该更多地使用JSON。当然,在MacOS上它没有被安装,所以首先要运行“cpan install JSON”,感谢https://dev59.com/omct5IYBdhLWcg3wh9xK#16382371。 - Ted

11

有一个Data::Dumper 模块可以实现这种类型的转换。


是的,但它会在字符串前面添加 $VAR1 = - Leon Timmermans
没错,很烦人但是可以解决。 - Greg Hewgill

9
使用 Data::Dump 替代 Data::Dumper。它基本上是相同的,只是没有那个烦人的 $VAR1 = ... 杂乱代码:
use Data::Dump "pp";
print pp({a => 1, b => 2, c => 3});

产生:

{ a => 1, b => 2, c => 3 }

如果您使用的是Windows系统,自从5.8版本起,Data::Dump已经预装在ActivePerl中。


无法在@INC中找到Data/Dump.pm - 它不是标准库。 - Hynek -Pichi- Vychodil
在ActivePerl 5.10,build 1004上,Data::Dump 1.08预装了。 - Kev
+1,顺便说一句,我之前没意识到这个模块的存在。它缺少某些像 HTML 格式化这样的附加组件,但没事。 - Kev
Kev:你是说好久以前的Data::Dumper能够产生HTML格式的输出吗?如果是,那真的很酷…… - j_random_hacker

2

另一种Swallow解决方案:

sub pp {
  my $h = shift();
  qq[{${\(join',',map"$_=>$h->{$_}",keys%$h)}}]
}
print pp({a => 1, b => 2, c => 3});

但是请使用Data::Dumper代替。

如果需要非常复杂的输出,你也可以使用:

use Data::Dumper;
use Perl::Tidy;
sub pp {
        local $Data::Dumper::Terse    = 1;
        local $Data::Dumper::Indent   = 0;
        my $source = Dumper(@_);
        my $result;
        Perl::Tidy::perltidy(
                source      => \$source,
                destination => \$result,
                argv        => [qw(-pbp -nst)]
        );
        return $result;
}

如果您希望某些键位先显示,可以使用以下方法(例如,我希望type排在第一位,position排在第二位):
    local $Data::Dumper::Sortkeys = sub {
            [   sort {
                            if    ( $b eq 'type' )     {1}
                            elsif ( $a eq 'type' )     {-1}
                            elsif ( $b eq 'position' ) {1}
                            elsif ( $a eq 'position' ) {-1}
                            else                       { $a cmp $b }
                            } keys %{ $_[0] }
            ];
    };

2

如果您有多级结构的潜力,上述解决方案中有几个问题。

具体来说,是这个标志:

$Data::Dumper::Terse    = 1;

正如Data::Dumper的perldoc页面所述,“terse”标志可能会生成非perl可解析的输出。

如果可能会有多层结构,则正确的做法是使用:

$Data::Dumper::Indent = 0;

这个方法保证可以被perl的eval函数解析,因此非常容易将其序列化为纯文本格式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接