Perl:给定一个任意字符串,你如何提取前N位?

时间:2010-11-08 17:02:09

标签: perl

给定一个字符串$ old_str,我试图将前N位(不是字节)提取到$ new_str中。我一直在阅读包文档和perlpacktut,但我绝望地感到困惑。这就是我目前所处的位置:

my $old_str = "9876543210";                                                     
# Extract the first 5 bits
my $new_str = pack("B5", unpack("B*", $old_str));
printf "%#b | %#b\n", $new_str, $old_str;

这会产生:

0b1000 | 0b1001001100101100000001011011101010

但我想要这个:

0b10010 | 0b1001001100101100000001011011101010

3 个答案:

答案 0 :(得分:1)

你想要vec内置:vec

答案 1 :(得分:0)

您可以使用unpack

my $bit_string = unpack( 'b*', $old_str );

它将创建一个80'1(char 0x31s)和'0'(char 0x30s)的字符串。在Windows上,您可能需要添加reverse

答案 2 :(得分:0)

我不确定你在这里要做什么。 unpack("B*", $old_str)创建一个包含以下位的位字符串(为了便于阅读而添加空格):

00111001 00111000 00110111 00110110 00110101 00110100 00110011 00110010 00110001 00110000

...换句话说,对应于字符的ASCII数字的位字符串:

$ perl -E "printf('%#b ', ord) for split(//, '9876543210')"
0b111001 0b111000 0b110111 0b110110 0b110101 0b110100 0b110011 0b110010 0b110001 0b110000

然后你做pack('B5', '00111001…')这似乎有点复杂。看起来pack返回一个由第一个8元组(11001)中最右边五位组成的字节。这给出了56或8字符串(因为8的ASCII是56):

$ perl -E "say ord pack('B5', '00111001…')"
56
$ perl -E "say pack('B5', '00111001…')"
8

当你printf字符串时,你得到数字8的二进制数字表示法:

$ perl -E "say printf '%#b', '8'"
0b10001

(这很疯狂。)