【问题标题】:How to display readable UTF-8 strings with Data::Dumper?如何使用 Data::Dumper 显示可读的 UTF-8 字符串?
【发布时间】:2018-05-23 12:58:08
【问题描述】:

我在结构中有一些 UTF-8 编码的字符串,出于调试目的,我使用 Data::Dumper 转储这些字符串。

一个小测试用例是:

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

输出

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

但我想看看

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

当然,我的结构要复杂得多。 调试时如何使转储结构中的字符串可读?也许我必须在warn/say 之前以某种方式通过chr 处理输出?

【问题讨论】:

  • 我还鼓励您发布答案。当我找不到它时,这很好用在 Stackoverflow 上。 (答案不需要很详细,只要用一个简单的例子就足够了。)另一个很好的来源是Accents not respected in printing out with data::dumper,但它没有提到Encode的方式,所以我不会将其标记为重复

标签: perl debugging unicode utf-8 data-dumper


【解决方案1】:

仅用于调试:

#!/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 应该是 UTF-8 使用“binmode STDOUT, ':encoding(UTF-8)';”从"Sau\x{f0}anes Airport" 切换(转义ISO-8859-1;不能将eval-ed 退回假设 UTF-8)到'Sauðanes Airport'(未转义的 UTF-8)。这是某种错误吗?我不开心。
  • @DavidTonhofer 无论您喜欢哪里,都可以?
  • @ernix 一个要点存在于gist.github.com/dtonhofer/29c8d561c911cc93052f2bb2181ee75e——尽管不同实现的输出不同,但我无法重现我之前遇到的回读问题。读取产生正确的字符串。在 Fedora 29 和 CentOS 7.6 上测试。我必须检查我在工作中设置的处理管道以查找错误。
  • @DavidTonhofer 试试Useqq(1),我也分叉/回复了你的要点。
【解决方案2】:

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

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。我建议您查看 SO 的 official How to Answer article 以及来自 Jon Skeet 的综合 blog post
【解决方案3】:

抱歉,我已经测试了 eval 整个转储,并且对我的数据有些反感,所以

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

【讨论】:

  • 粘贴的代码需要更多信息给其他人。请编辑您的帖子以添加更多信息,说明您的代码为何优于所选代码。
  • 再次抱歉,我有带有符号 $ 和 @ 的数据
猜你喜欢
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
  • 2017-05-04
  • 2014-07-18
  • 2018-08-18
  • 2011-06-15
  • 1970-01-01
  • 2011-06-14
相关资源
最近更新 更多