关于 perl 解包

Posted

技术标签:

【中文标题】关于 perl 解包【英文标题】:Regarding perl unpack 【发布时间】:2012-07-03 02:03:35 【问题描述】:

我打算在文件中使用 unpack。首先我用一个字符串测试。当我在字符串中有嵌入空间时,下面的脚本将其显示为空。当我用文件空间进行测试时,可以正确读取。不知道为什么当我使用字符串时它会将其更改为 null。我可以在读取固定长度文件时使用 unpack 吗?我是否需要考虑尾随空格或其他任何东西?

#!/usr/local/bin/perl

use strict;
use warnings;
my $str="hek kaaa";
print "<$str>\n";
foreach(unpack("(A1)*", $str)) 
    print sprintf("%x", ord), " ";


Output:
<hek kaaa>
68 65 6b 0 6b 61 61 61

非常感谢您的回复。在下面粘贴我的查询

当 perl 程序从一个文本文件中读取并使用“A”格式解压时工作正常。第一行我在 A 和 D 之间的第一个字段中有一个嵌入空间。标签变量打印为“A D3”。但是当我有一个变量 $str="A D3" 并以下面的方式解压缩时,它在 A 之后有一个空值。从文件和变量读取时它的工作方式有何不同?

foreach(unpack("(A1)*", $str)) 
    print sprintf("%x", ord), " ";

它显示为十六进制输出 41 0 44 33

cat test.txt
A D37845566974923342XYZ24023984
QRW49327408234028434ERD24448009

 my $file = 'test.txt';

open(my $data, '<', $file) or die "Could not open '$file'\n";
while (my $line = <$data>) 
    print $line;
    chomp $line;
    my ($label, $source, $dest, $type, $value) = unpack ("A4 A8 A8 A4 A8", $line);
    print "LABEL: $label SOURCE: $source DEST: $dest TYPE: $type VALUE: $value\n";
    print "length of a string:" . length($line) . "\n";
    foreach(unpack("(a1)*", $label)) 
       print sprintf("%x", ord), " ";
    
    print "\n";


【问题讨论】:

您真正想要完成什么?看起来你正在以一种非常尴尬的方式来处理它。 【参考方案1】:

pack/unpack 文档中的这个小块很容易错过:

“a”、“A”和“Z”类型只吞噬一个值,但是 将其打包为长度计数的字符串,用空值填充 或必要的空格。 开箱时,“A”字带 尾随空格和空值,“Z”删除所有内容 在第一个 null 之后,“a”逐字返回数据。

作为一种解决方法,您可以在模板中使用aZ 而不是A

$ perl -e 'print ord unpack("A", " ")'
0

$ perl -e 'print ord unpack("a", " ")'
32

$ perl -e 'print ord unpack("Z", " ")'
32

【讨论】:

非常感谢您提供的信息。当我有一个文本文件时 这很有帮助...感谢您的澄清。【参考方案2】:

pack 'A' 用空格填充,因此unpack 'A' 删除尾随空格。 (实际上是空格和 NUL。)

>perl -E"say(($ARGV[0] eq unpack('A20', pack('A20', $ARGV[0]))) ? 1 : 0)" abc
1

你想要“a”。

unpack("(a1)*", $str)

也就是说,“1”是多余的。

unpack("(a)*", $str)

最后,split 更常用于此。

split(//, $str)

【讨论】:

非常感谢您提供的信息。我编辑了我的问题。你能回复一下吗 是什么让你认为它不是文件中的 NUL? for ("A\x20D3", "A\x00D3") print "$_: "; print sprintf("%02x ", $_) for unpack("C*", $_); print "\n";

以上是关于关于 perl 解包的主要内容,如果未能解决你的问题,请参考以下文章

Perl 解包和换行符

Perl 中的解包功能要求

Perl 打包/解包/移位

Qt 等效于 Perl 打包/解包

perl 将函数解包到 python

如何在 C# 中复制 Perl 的解包功能?