正则表达式捕获不返回预期的数组
Regex capture not returning expected array
我正在尝试使用正则表达式生成捕获组数组,但捕获组没有捕获我期望的字符串。
我的输入类似于以下通用格式:
S2244060800027008209302B000A667A6201A6828E1976007A000A52820009A3420009B0FE1F
这个字符串有以下组成部分:
一个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;
我想要的输出是一个包含以下元素的数组:
@array = [406080, 0027, 0082, 0930, 2B00, 0A66, 7A62, 01A6, 828E, 1976, 007A, 000A, 5282, 0009, A342, 0009, B0FE]
但前面的正则表达式生成一个仅包含 3 字节地址和最后一个数据块的二元数组:
@array = [406080, B0FE]
这对我来说意味着我对正则表达式捕获组的工作方式有一个根本性的误解,我想澄清一下。
为了完整起见,这是我糟糕的解决方法:
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;
量化捕获组不会创建多个捕获组。它根据量词匹配,但只捕获最后一个匹配。
unpack更适合提取部分二进制数据:
#!/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;
我正在尝试使用正则表达式生成捕获组数组,但捕获组没有捕获我期望的字符串。
我的输入类似于以下通用格式:
S2244060800027008209302B000A667A6201A6828E1976007A000A52820009A3420009B0FE1F
这个字符串有以下组成部分: 一个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;
我想要的输出是一个包含以下元素的数组:
@array = [406080, 0027, 0082, 0930, 2B00, 0A66, 7A62, 01A6, 828E, 1976, 007A, 000A, 5282, 0009, A342, 0009, B0FE]
但前面的正则表达式生成一个仅包含 3 字节地址和最后一个数据块的二元数组:
@array = [406080, B0FE]
这对我来说意味着我对正则表达式捕获组的工作方式有一个根本性的误解,我想澄清一下。
为了完整起见,这是我糟糕的解决方法:
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;
量化捕获组不会创建多个捕获组。它根据量词匹配,但只捕获最后一个匹配。
unpack更适合提取部分二进制数据:
#!/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;