27

我最近编写了一个脚本,它解析单个二进制字节月份字段的文本表示。

(不要问:-{)

在摆弄 sprintf 一段时间后,我放弃了,做了这个;

our %months = qw / x01 1 
       x02 2
       x03 3 
       x04 4 
       x05 5 
       x06 6 
       x07 7 
       x08 8 
       x09 9 
       x0a 10 
       x0b 11 
       x0c 12 /;
...
my $month = $months{$text};

我逃脱了,因为我只使用 12 个数字,但是有没有更好的方法呢?

4

4 回答 4

37

如果你有

$hex_string = "0x10";

您可以使用:

$hex_val = hex($hex_string);

你会得到:$hex_val == 16

hex不需要0x字符串开头的“”。如果它丢失,它仍然会将十六进制字符串转换为数字。

您还可以使用oct基于前缀将二进制、八进制或十六进制字符串转换为数字:

  • 0b- 二进制
  • 0 - 八进制
  • 0x- 十六进制
于 2009-10-07T14:32:19.677 回答
7

请参见hex和/或oct

#!/usr/bin/perl

use strict;
use warnings;

my @months = map hex, qw/x01 x02 x03 x04 x05 x06 x07 x08 x09 x0a x0b x0c/;
print "$_\n" for @months;
于 2009-10-07T14:32:13.327 回答
3

如果我理解正确,您每月有 1 个字节 - 不是字符串“0x10”,而是其中包含 10 个字节。

这样,您应该使用unpack

my $in = "\x0a";
print length($in), "\n";
my ($out) = unpack("c", $in);
print length($out), "\n", $out, "\n"

输出:

1
2
10

如果输入的是 3 个字符,比如“x05”,那么修改也很简单:

my $in = "x0a";
my $out = hex($in);
于 2009-10-07T14:47:01.893 回答
0

这是另一种直接转换字符串中包含的十六进制可能更实用的方法。

这利用了 s/// 上的 /e(e 表示评估)正则表达式修饰符。

从这个字符串开始:

$hello_world = "\\x48\\x65\\x6c\\x6c\\x6f\\x20\\x57\\x6f\\x72\\x6c\\x64";

十六进制转字符:

print $hello_world =~ s/\\x([0-9a-fA-F]{2})/chr hex $1/gre;

十六进制转十进制数:

print $hello_world =~ s/\\x([0-9a-fA-F]{2})/hex $1/gre;

删除 /r 修饰符以就地替换字符串。

有一天,我使用了一个 python 脚本来处理二进制文件,但我被一个只包含十六进制数字的字节文字 (b'\x09\xff...') 困住了。我设法用一个作为上述变体的单行来取回我的字节。

于 2021-08-24T07:26:09.623 回答