1 regex perl regex-group regex-greedy
我正在尝试使用正则表达式生成一组捕获组,但是捕获组没有捕获我期望的字符串。
我的输入类似于以下常规格式:
S2244060800027008209302B000A667A6201A6828E1976007A000A52820009A3420009B0FE1F
Run Code Online (Sandbox Code Playgroud)
该字符串具有以下组成部分:4个字符的前缀,3个字节的地址,一系列2字节的数据块,1个字节的行终止符。
我只关心地址和数据块。
我尝试使用的正则表达式是:
/\w{4}(\w{6})(\w{4})+/;
(在执行正则表达式之前,我有一个使用子字符串解析输入的精巧解决方案,但我讨厌它……)
原始的非功能代码如下:
open IN, "<$ARGV[0]" or die "Could not open '$ARGV[0]': $!\n";
open OUT, ">$ARGV[0].txt" or die "Could not open '$ARGV[0].txt': $!\n";
while (<IN>)
{
print OUT join(" ",/^\w{4}(\w{6})(\w{4})+/)."\n";
}
close IN;
close OUT;
Run Code Online (Sandbox Code Playgroud)
我想要的输出是一个包含以下元素的数组:
@array = [406080, 0027, 0082, 0930, 2B00, 0A66, 7A62, 01A6, 828E, 1976, 007A, 000A, 5282, 0009, A342, 0009, B0FE]
Run Code Online (Sandbox Code Playgroud)
但是前面的正则表达式会导致一个仅包含3个字节地址和最后一个数据块的两个元素数组:
@array = [406080, B0FE]
Run Code Online (Sandbox Code Playgroud)
对我而言,这意味着我对正则表达式捕获组的工作方式有一个基本的误解,我想澄清一下。
仅出于完整性考虑,这是我糟糕的解决方法:
open IN, "<$ARGV[0]" or die "Could not open '$ARGV[0]': $!\n";
open OUT, ">$ARGV[0].txt" or die "Could not open '$ARGV[0].txt': $!\n";
while (<IN>)
{
print OUT substr($_, 4, 6)." ".join(" ",substr($_, 10) =~ /\w{4}/g)."\n";
}
close IN;
close OUT;
Run Code Online (Sandbox Code Playgroud)
量化捕获组不会创建多个捕获组。它根据量词进行匹配,但是仅捕获最后一个匹配项。
解压缩更适合提取部分二进制数据:
#!/usr/bin/perl
use warnings;
use strict;
my $s = 'S2244060800027008209302B000A667A6201A6828E1976007A000A52820009A3420009B0FE1F';
my $exp = [qw[ 406080 0027 0082 0930 2B00 0A66 7A62 01A6 828E 1976 007A 000A 5282 0009 A342 0009 B0FE ]];
my @result = unpack 'x4A6(A4)*', $s;
die unless '1F' eq pop @result;
use Test::More tests => 1;
is_deeply \@result, $exp;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
61 次 |
| 最近记录: |