正则表达式捕获未返回预期的数组

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)

cho*_*oba 5

量化捕获组不会创建多个捕获组。它根据量词进行匹配,但是仅捕获最后一个匹配项。

解压缩更适合提取部分二进制数据:

#!/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)