【发布时间】:2016-06-28 23:07:52
【问题描述】:
在使用pack 构建字符串时,我尝试重新排序字段,但我似乎无法让pack 做我想做的事。例如,我想用 abc 在偏移量 12、defg 在偏移量 8 和 hi 在偏移量 3 填充一个字符串(以及任何东西,大概是空格或 \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";
'
这适用于字符串中任何顺序的unpacking 字段。但是对于packing,它\0-填充并截断为documented。有没有办法阻止它从\0-填充和截断而不重新排序pack 模板以从左到右生成字段?
从外部来源读取字段规范时会出现此问题。当然,可以安排pack 模板以从左到右的顺序生成,并且可以重新排序结果列表以匹配外部字段规范。但是动态重新定位pack“光标”肯定会很方便,而无需填充中间位置或截断。
在上面的代码中,如果pack(...) 的返回值与$str 相同,并且. 有任何字节(例如空白或\0),我会很高兴。
【问题讨论】:
-
我不认为
pack可以简单地尊重字符串中其他位置的内容,如果这就是你的意思的话。它连接起来。这是substr的工作(但当时只有一个)。 -
那么在
3和hi和8之间,您想在其他地方做什么?$str的原件?那么那些被解包的范围会发生什么——它们是否也保持原样(所以它们在输出字符串中被复制)? -
@zdim 在这一点上,我并不真正关心其他职位。这个问题是关于如何根据包模板重新排列
pack参数中字段位置的一般问题。当然,如果能够选择将它们设为空白或 NUL,那就太好了。 -
好的。但是,人们必须选择如何处理它们——或者,我们要写什么?如果是“重新订购”,则可能意味着
3-5的内容现在位于12-14(反之亦然),这很好。或者,也许您想要“空白”(空格)。您是重新排序一个 16 字符长的字符串,还是从 a 字符串中挑选元素并写出一个 16 字符长的字符串,其余为 .... 零?空间?空(喘气)?有很好的解决方案,但整个工作是什么很重要。或者我可能完全误解了它。你能发布一些输入和输出——来源和你想要得到的东西吗? -
@JohnWiersba zdim 的第一条评论就是你的答案:pack 不会那样做。如果您将问题修改为“我如何在 perl 中执行此操作?”当然有很多方法。甚至可以关闭包模板的方法,如果这是必要的话。但是,如果问题是“我如何使用包来做到这一点?”答案是“你没有”:)