如何在perl中转储字符串以查看是否存在任何字符差异?

时间:2012-03-16 00:10:32

标签: perl unicode encoding character-encoding dump

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

4 个答案:

答案 0 :(得分:5)

我推荐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,因为广角,但不是第一个?)

答案 1 :(得分:4)

对于大多数用途,使用Useqq的{​​{3}}都可以。

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标志),请使用Data::Dumper

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 :(得分:2)

你试过Test::LongString吗?尽管它确实是一个测试模块,但它可以很方便地向您显示字符串中的差异。它侧重于不同的部分而不是向您显示整个字符串,并使\x{}转义为特殊字符。

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

答案 3 :(得分:1)

您需要转储任何字符串:

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;

我不知道为什么在wolrd中你会使用误导性的utf8::all。它不是一个核心模块,你似乎在知道它真正在做什么时遇到了一些麻烦。如果你明确地使用了进入它的各个核心部分,也许你会更好地理解它。