如何使用Data::Dumper显示可读的UTF-8字符串?

7

我有一些以UTF-8编码的字符串,它们存储在结构体中,我正在使用Data::Dumper进行调试目的的转储。

一个小测试案例如下:

use utf8;
use Data::Dumper;
say Dumper({да=>"не"}

它输出

{
  "\x{434}\x{430}" => "\x{43d}\x{435}"
};

但我想看。
{
  "да" => "не"
};

当然,我的结构相当复杂。在调试时如何使转储结构中的字符串可读?也许我需要在使用warn/say之前通过chr处理输出?


2
我也鼓励您发布一个答案。当我找不到时,在Stackoverflow上有这个答案是很好的。(答案不必详尽,只需用简单的示例概括即可。)另一个好的来源是Accents not respected in printing out with data::dumper,但它没有提到Encode的方法,所以我不会将其标记为重复。 - zdim
3个回答

7

仅用于调试:

#!/usr/bin/perl
use strict;
use warnings;
use v5.10;
use utf8;
use Data::Dumper;
binmode STDOUT, ':utf8';

CASE_1: {
    # Redefine Data::Dumper::qquote() to do nothing
    no warnings 'redefine';
    local *Data::Dumper::qquote = sub { qq["${\(shift)}"] };
    # Use the Pure Perl implementation of Dumper
    local $Data::Dumper::Useperl = 1;

    say Dumper({да=>"не"});
}

CASE_2: {
    # Use YAML instead
    use YAML;
    say Dump({да=>"не"});
}

CASE_3: {
    # Evalulate whole dumped string
    no strict 'vars';
    local $Data::Dumper::Terse = 1;

    my $var = Dumper({да=>"не"});
    say eval "qq#$var#" or die $@;
}

__END__
$VAR1 = {
          "да" => "не"
        };

---
да: не

{
  "да" => "не"
}

仅通过切换到Data::Dumper的纯Perl实现,输出(写入STDOUT,我已告诉Perl应使用"binmode STDOUT, ':encoding(UTF-8)';"进行编码)从转义的ISO-8859-1的"Sau\x{f0}anes Airport"(假定为UTF-8时无法eval回)切换为未转义的UTF-8的'Sauðanes Airport'。这是某种bug吗?我不感到高兴。 - David Tonhofer
@DavidTonhofer 你喜欢的地方,Gist 可以吗? - ernix
@ernix 在 https://gist.github.com/dtonhofer/29c8d561c911cc93052f2bb2181ee75e 上存在一个要点--尽管不同实现之间的输出不同,但我无法再次复现我之前遇到的读回问题。读取得到正确的字符串。在 Fedora 29 和 CentOS 7.6 上进行了测试。我必须检查我在工作中设置的处理管道以查找一些错误。 - David Tonhofer
@DavidTonhofer 试试 Useqq(1),我也对你的gist进行了fork/回复。 - ernix

1

print Dumper(%mydata) =~ s/\\x\{([0-9a-f]{2,})\}/chr hex $1/ger;


1
虽然这段代码可能回答了问题,但提供关于为什么和/或如何回答问题的额外上下文信息可以提高其长期价值。我建议您查看SO的官方如何回答文章,以及来自Jon Skeet的全面博客文章 - Aleksey Potapov

-1

抱歉,但我已经测试了整个转储并对我的数据产生了一些疑惑。

Data::Dumper->new(\@_)
  ->Indent(1)->Sortkeys(1)->Terse(1)->Useqq(0)->Dump
  =~ s/((?:\\x\{[\da-f]+\})+)/eval '"'.$1.'"'/eigr;

贴上的代码需要更多信息以供他人参考。请编辑您的帖子,添加更多信息,说明为什么您的代码比所选代码更好。 - Syfer
抱歉,我的数据中包含符号 $ 和 @。 - Mihail N

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