在使用pack
构建字符串时,我试图重新排序字段,但我似乎无法让pack
做我想做的事情。例如,我想在偏移量12处填充一个字符串,在偏移量12处填充abc
,在偏移量8处填充defg
,在偏移量3处填充hi
(以及任何可能是空格或\0
的偏移量0-2和5-7)。
perl -e '
use strict; use warnings;
my $str = "...hi...defgabc";
my $fmt = q{@12 a3 @8 a4 @3 a2};
my @a = unpack $fmt, $str;
print "<$_>\n" for @a;
print "\n";
print unpack("H*", pack($fmt, @a)), "\n";
'
这对于字符串以外的任何顺序的unpack
ing字段来说都很好。但是对于pack
ing,它将\0
-fills和截断为记录在案。有没有任何方法阻止它从\0
-filling和截断而不重新排序pack
模板,以产生从左到右的字段?
从外部源读取字段规范时会出现这个问题。当然,可以将pack
模板按从左到右的顺序排列,由此产生的列表可以重新排序以符合外部字段规范。但是,在不填充中间位置或截断位置的情况下,动态地重新定位pack
“游标”是非常方便的。
在上面的代码中,如果pack(...)
的返回值与用于.
的任何字节(例如.
或\0
)的返回值相同,我会很高兴。
发布于 2016-06-29 13:55:38
显然,pack
没有办法直接做到这一点。这里有一种方法可以避免循环和使用substr
。然而,与unpack
的易懂性相比,它并不是很令人满意。我希望我误解了pack
文档中的一些内容,即允许pack
与unpack
相反,用于在pack
ed字符串中放置字段。
use strict; use warnings;
my $str = "...hi...defgabc";
my @pos = (
{ pos => 12, len => 3 },
{ pos => 8, len => 4 },
{ pos => 3, len => 2 },
);
my $fmt = join " ", map { "\@$_->{pos} a$_->{len}" } @pos;
# q{@12 a3 @8 a4 @3 a2};
my @a = unpack $fmt, $str;
print "<$_>\n" for @a;
print "\n";
my @sorted_idxes =
sort { $pos[$a]{pos} <=> $pos[$b]{pos}
or $pos[$a]{len} <=> $pos[$b]{len} }
0..$#pos;
my $sorted_fmt = join " ",
map { "\@$pos[$_]->{pos} a$pos[$_]->{len}" } @sorted_idxes;
my $out = pack $sorted_fmt, @a[@sorted_idxes];
$out =~ s/\0/./g;
print "$out\n";
发布于 2016-06-29 06:27:56
不能让pack写入字符串中的特定位置。它不使用可以重新定位的“游标”在字符串周围移动--但是它只是将给定给它的所有东西连接起来,然后用它编写一个新的字符串。
包装模板,列表 获取一个值列表,并使用模板提供的规则将其转换为字符串。得到的字符串是转换值的级联。..。
在页面的下方,文档还说
您必须自己进行任何调整或填充,例如,在打包时插入足够的
"x"
es。pack
和unpack
无法知道字符的去向或来自何处,因此它们将输出和输入处理为扁平的字符序列。
当然,您可以以任何您想要的方式写出字符串,但是只有通过重新安排模板(如果尝试按顺序排列,它会根据每个@
的需要填充,从零到覆盖每个值),以及写出或填充“中间位置”。所以你可以说
my $str = "...hi...defgabc";
my $fmt = q{@12 a3 @8 a4 @3 a2};
my @parts = unpack $fmt, $str;
# Add to @parts and template what need be in between or change $fmt to get all
my $res = pack "A3A4A2", @parts;
然后,您可以提取原始字符串的所有部分,重新排列它们或构建合适的索引掩码,并对其进行pack
。我知道你知道这一点,也不想要它,但pack
除了写出整个字符串之外,别无他法。
至于编写字符串的部分,这正是底座的工作。因此,也许您可以使用@fmt
和/或@parts
编写一个小循环,其中substr
将在需要的位置替换给定长度的序列。然而,pack
-ing --这一切都应该是一次有效得多的。
https://stackoverflow.com/questions/38087689
复制相似问题