perl - 如何为每个字节打印utf8代码点

问题描述 投票:1回答:2

我正在尝试为所有可能的字节值打印代码点。

我的测试文件:

$ perl -e ' open($fh,">raw_bytes.dat");while($i++<256){ print $fh chr($i-1) } close($fh)'

$ ls -l raw_bytes.dat
-rw-rw-r--+ 1 uuuuu Domain Users 256 Mar 20 15:41 raw_bytes.dat
$ 

什么应该进入下面的#--->部分,以便我以十六进制打印utf8 $ x的代码点?

perl -e ' use utf8; open($fh,"<raw_bytes.dat");binmode($fh);
          while($rb=read($fh,$x,1)) { utf8::encode($x);
          #--->
          } ' 

我使用printf尝试了%02x,但它没有用。此外,我希望解决方案仅使用核心模块。

perl
2个回答
2
投票

使用unpack('H*')

$ perl -e '$x="\x80"; utf8::encode($x); print unpack("H*", $x), "\n"'
c280

对于你得到的示例文件

$ perl -e 'open($fh, "<", "raw_bytes.dat"); binmode($fh); 
           while ($rb=read($fh,$x,1)) { utf8::encode($x);
               print unpack("H*", $x), "\n";
           }'
00
01
02
03
...
7f
c280
c281
c282
c283
...
c3bd
c3be
c3bf

变种:

$ perl -e '$x="\x80"; utf8::encode($x);
           print uc(unpack("H*", $x)), "\n"'
C280

$ perl -e '$x="\x80"; utf8::encode($x);
           ($r = uc(unpack("H*", $x))) =~ s/(..)/\\X\1/g;
           print "$r\n"'
\XC2\X80

# a little bit pointless example, but assume that $x is a provided Perl scalar....
$ perl -e '$x="\N{U+0080}\N{U+0081}";
           printf("U+%04x ", ord($_)) foreach(split(//, $x));
           print "\n";'
U+0080 U+0081

请记住之间的区别

  • 一个持有原始字符串的标量:split(//)返回八位字节,例如\x80
  • 标量持有正确编码的字符串:split(//)返回字符,例如\N{U+0080}

2
投票

我使用printf尝试了%02x,但它没有用。

您可以使用

printf "%vX\n", $x;

perldoc sprintf说:

矢量标志

该标志告诉Perl将提供的字符串解释为整数向量,对应于字符串中的每个字符。 Perl依次将格式应用于每个整数,然后使用分隔符(默认为点)连接结果字符串。这对于在任意字符串中显示字符的序数值非常有用。

© www.soinside.com 2019 - 2024. All rights reserved.