Perl:使用正则表达式将十六进制编码的字符串解析为数组
Posted
技术标签:
【中文标题】Perl:使用正则表达式将十六进制编码的字符串解析为数组【英文标题】:Perl: parse hex-encoded string into array with regex 【发布时间】:2011-03-16 21:40:49 【问题描述】:我是 Perl 开发的新手,我想执行以下任务:
我的脚本接收十六进制编码的字符串作为命令行参数。然后我必须解码这个字符串并将其写入输出文件,如 C++ 数组,并根据给定的数据进行初始化。例如:
perl myscript.pl DEADBABEDEADBEEF
和输出类似
const boost::array<char, 8> MyArray = 0xDE, 0xAD, 0xBA, 0xBE, 0xDE, 0xAD, 0xBE, 0xEF ;
使用 Perl 正则表达式的正确方法是什么?当然,我可以用子字符串循环执行它,但我相信应该有更优雅的方式。
编辑:输入字符串是固定长度的。
【问题讨论】:
分割/映射呢?除非您确定输入字符串的长度是固定的,否则我怀疑 regexp 是否是一个不错的选择。 是的,在这种情况下,我确信我的输入字符串是固定长度的。我会更新问题。 【参考方案1】:解压怎么样?
print join ",", unpack("(A2)*", "DEADBABEDEADBEEF");
更正 - 您需要一个映射来为解包返回的每个元素添加前缀“0x”
print join ",", map '0x' . $_ unpack("(A2)*", "DEADBABEDEADBEEF");
【讨论】:
【参考方案2】:这个怎么样:
my $input = $ARGV[0];
die "Fouled up input" unless $input =~ /^(?:[0-9A-F]2)+$/i;
my $bytes = length ($input) / 2;
print "const boost::array<char, $bytes> MyArray = ";
while ($input =~ s/([0-9A-F]2)//i)
# print $input # to see how this works, see comment.
print "0x$1, ";
print ";\n";
【讨论】:
谢谢,您的回答是正确的。但第二个答案也是正确的。我不确定我应该投票给谁。 :) 我对您的代码有疑问:为什么在声明$input =~ s/([0-9A-F]2)//
中您将 s/// 的第二个参数留空?在这种情况下,这意味着什么?
每次只删除前两个字符。将print $input
放入循环中,您将看到它是如何工作的。
@Kinopiko,好的,我知道了。谢谢。【参考方案3】:
试试这个:
my $hex = "DEADBABEDEADBEEF";
my @a = map "0x$_", $hex =~ /(..)/g;
它是如何工作的:
首先,列表上下文中的$hex =~ /(..)/g
捕获所有2 个字符的子字符串(/g
标志表示全局匹配)。然后map()
获取列表并将其转换为另一个列表,对第一个列表的每个元素使用"0x$_"
表达式($_
这里是元素的别名)。
另见perldoc -f map。
【讨论】:
谢谢,您的脚本正在运行。但是你能解释一下细节吗?那里发生了什么,操作之间的“,”(逗号)是什么?正如我所说,我对 Perl 很陌生。 :) @Haspemulator:这是一项艰巨的任务。尝试perldoc -f map
获取地图函数的文档,并尝试perldoc perlre
获取正则表达式的文档。
很好的解决方案,但最好将从字符串中检索到的两位数字限制为合法的十六进制数字。即my @a = map "0x$_", $hex =~ /([\da-eA-E]2)/g;
,不是吗?以上是关于Perl:使用正则表达式将十六进制编码的字符串解析为数组的主要内容,如果未能解决你的问题,请参考以下文章