【问题标题】:How can I dump a string in perl to see if there are any character differences?如何在 perl 中转储字符串以查看是否存在字符差异?
【发布时间】:2012-04-01 13:41:23
【问题描述】:

我偶尔会遇到字符串略有不同的问题,在某些情况下utf8::all 改变了行为,所以我认为细微的差异是 unicode。我想以这样一种方式转储字符串,以便我可以看到差异。我有哪些选择?

【问题讨论】:

    标签: perl unicode encoding character-encoding dump


    【解决方案1】:

    对于大多数用途,Data::DumperUseqq 都可以。

    use utf8;
    use Data::Dumper;
    local $Data::Dumper::Useqq = 1;
    print(Dumper("foo–bar"));
    print(Dumper("foo-bar"));
    

    输出:

    $VAR1 = "foo\x{2013}bar";
    $VAR1 = "foo-bar";
    

    如果您需要内部详细信息(例如 UTF8 标志),请使用 Devel::Peek

    use utf8;
    use Devel::Peek;
    Dump("foo–bar");
    Dump("foo-bar");
    

    输出:

    SV = PV(0x328ccc) at 0x1d6a0c4
      REFCNT = 1
      FLAGS = (PADTMP,POK,READONLY,pPOK,UTF8)
      PV = 0x1d6d52c "foo\342\200\223bar"\0 [UTF8 "foo\x{2013}bar"]
      CUR = 9
      LEN = 12
    SV = PV(0x328dcc) at 0x32b594
      REFCNT = 1
      FLAGS = (PADTMP,POK,READONLY,pPOK)
      PV = 0x1d6d50c "foo-bar"\0
      CUR = 7
      LEN = 12
    

    【讨论】:

    【解决方案2】:

    你试过Test::LongString吗?尽管它确实是一个测试模块,但它可以方便地向您展示字符串中出现差异的位置。它专注于不同的部分,而不是向您展示整个字符串,并且它使 \x{} 转义为特价。

    我想看看utf8::all 改变行为的例子,即使只是为了看看一个有趣的边缘情况。

    【讨论】:

    • 它涉及密码哈希和数据库。这不好玩,我从来没有弄清楚为什么会这样。否则我会的。
    • 注意:不确定之前是 utf8::all,但this 似乎是我的问题
    【解决方案3】:

    你只需要转储任何字符串:

    printf "U+%v04X\n", $string;
    

    你可以用它来格式化一个字符串:

    ($print_string = $string) =~ s/([^\x20-\x7E])/sprintf "\\x{%x}", $1/ge;
    

    甚至

    use charnames ();
    ($print_string = $string) =~ s/([^\x20-\x7E])/sprintf "\\N{%s}", charnames::viacode(ord $1)/ge;
    

    我不知道为什么在世界上您会使用具有误导性的名称utf8::all。它不是一个核心模块,你似乎很难知道它到底在做什么。如果您明确使用其中的各个核心部分,也许您会更好地理解它。

    【讨论】:

    • 我以前从未想过我的问题是在哪里发生的,甚至是如何发生的。不同的地方有各种各样的魔法猴子我的作品,例如。 dancer 插件数据库开启 utf8, iirc
    • 我只知道我在点 A 输入 'foo',得到 sha X,我在点 B 输入它,得到 sha Y,始终如一。我将 utf8::all 添加到模块中,问题就消失了。我不喜欢完全不理解。
    【解决方案4】:

    我推荐the Devel::Peek module in the Perl core中的Dump函数:

    $ perl -MDevel::Peek -e 'Dump "abc"'
    SV = PV(0x10441500) at 0x10491680
      REFCNT = 1
      FLAGS = (PADTMP,POK,READONLY,pPOK)
      PV = 0x10442224 "abc"\0
      CUR = 3
      LEN = 4
    
    $ perl -MDevel::Peek -e 'Dump "\x{FEFF}abc"'
    SV = PV(0x10441050) at 0x10443be0
      REFCNT = 1
      FLAGS = (PADTMP,POK,READONLY,pPOK,UTF8)
      PV = 0x10449bc0 "\357\273\277abc"\0 [UTF8 "\x{feff}abc"]
      CUR = 6
      LEN = 8
    

    (您看到FLAGS 在第二个示例中如何包含UTF8,因为宽字符,但在第一个示例中没有?)

    【讨论】:

    • Devel::Peek 可以解决其他问题,因为字符串中实际上没有特殊字符,但存在 UTF8 标志。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 2010-10-15
    • 2020-11-29
    • 2011-07-30
    相关资源
    最近更新 更多