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:使用正则表达式将十六进制编码的字符串解析为数组的主要内容,如果未能解决你的问题,请参考以下文章

解析posix与perl标准的正则表达式区别

Python 中的 Perl 兼容正则表达式 (PCRE)

PHP整理笔记八正则表达式

如何使用正则表达式解析 Perl 中引用的 CSV?

Perl - 正则表达式匹配的输出非常奇怪,确实

PHP -- Perl风格正则表达式