Perl - 正则表达式 - 组捕获
Perl - Regex - Group Capturing
我在执行搜索并替换为捕获组时遇到了一些问题。
我正在创建 3 个组并尝试替换第 1 组和第 3 组,同时保持第二组不变。实际结果给我的输出是正确替换了第一组和第二组,而第三组没有被替换。
这是我试过的方法:
perl -p -e 's|(\x80\xbb)(.{4,})(\x00\x00\x00)|\xc6\x83\x00\x00\x01|g' "" > ".tmp"
输入:\x80\xbb`\xef\x00\x00\x00
预计:\xc6\x83`\xef\x00\x00\x01
我不是最擅长正则表达式的,所以请帮助我。我也愿意接受涉及 sed 的答案。
真实内容:
\x81\x00\x00\x00\x80\xbb`\xef\x00\x00\x00u!L\x89<$H\x8d\x15\x91\xec\x12\x00L\x89\xefL\x89\xf6H\x8bM\xc8L\x8bE\xd0M\x89
xxd:
0x000073ff 80bb 60ef 0000 0075 214c 893c 2448 8d15 ..`....u!L.<$H..
0x0000740f 91ec 1200 4c89 ef4c 89f6 488b 4dc8 4c8b ....L..L..H.M.L.
0x0000741f 45d0 4d89 e1e8 5700 0000 c783 2c09 0000 E.M...W.....,...
0x0000742f 0000 0000 f20f 1005 652b 1200 0f29 8330 ........e+...).0
0x0000743f 0900 0048 b800 0000 0000 00f0 bf48 8983 ...H.........H..
编辑:我忘了说表示是十六进制的。
我认为任何组都不会被替换,至少在我尝试时是这样。问题是 .{4,}
表示“至少四个字符”,但只有两个:\x60\xef
.
或者,如果您的输入确实是十六进制表示,请从代码中删除 \x
:在双引号中,\x60
表示字符 `
,而不是数字 6
和 0
。它们由 60
表示,没有任何前缀。
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
use Test::More;
my $in = "\x80\xbb\x60\xef\x00\x00\x00";
(my $out = $in) =~ s/(\x80\xbb)(.{2,})(\x00\x00\x00)/\xc6\x83\x00\x00\x01/g;
is $out, "\xc6\x83\x60\xef\x00\x00\x01";
my $in2 = '80bb60ef000000';
(my $out2 = $in2) =~ s/(80bb)(.{4,})(000000)/c683000001/g;
is $out2, 'c68360ef000001'; # ~~~~
注意 0
以防止将 0
解释为变量名称的一部分。
在代码中,您只保留两个连续字节进行替换,一个捕获组就足够了。
以下代码演示了如何将十六进制字符串转换为二进制值,进行必要的替换并将二进制输出为文本字符串。
use strict;
use warnings;
use feature 'say';
my($in,$out);
$out = $in = pack 'H*', '8100000080bb60ef00000075214c893c24488d1591ec12004c89ef4c89f648';
$out =~ s!\x80\xbb(.{2})\x00\x00\x00!\xc6\x83\x00\x00\x01!;
say 'in: ' . unpack('H*',$in);
say 'out: ' . unpack('H*',$out);
输出
in: 8100000080bb60ef00000075214c893c24488d1591ec12004c89ef4c89f648
out: 81000000c68360ef00000175214c893c24488d1591ec12004c89ef4c89f648
我在执行搜索并替换为捕获组时遇到了一些问题。
我正在创建 3 个组并尝试替换第 1 组和第 3 组,同时保持第二组不变。实际结果给我的输出是正确替换了第一组和第二组,而第三组没有被替换。
这是我试过的方法:
perl -p -e 's|(\x80\xbb)(.{4,})(\x00\x00\x00)|\xc6\x83\x00\x00\x01|g' "" > ".tmp"
输入:\x80\xbb`\xef\x00\x00\x00
预计:\xc6\x83`\xef\x00\x00\x01
我不是最擅长正则表达式的,所以请帮助我。我也愿意接受涉及 sed 的答案。
真实内容:
\x81\x00\x00\x00\x80\xbb`\xef\x00\x00\x00u!L\x89<$H\x8d\x15\x91\xec\x12\x00L\x89\xefL\x89\xf6H\x8bM\xc8L\x8bE\xd0M\x89
xxd:
0x000073ff 80bb 60ef 0000 0075 214c 893c 2448 8d15 ..`....u!L.<$H..
0x0000740f 91ec 1200 4c89 ef4c 89f6 488b 4dc8 4c8b ....L..L..H.M.L.
0x0000741f 45d0 4d89 e1e8 5700 0000 c783 2c09 0000 E.M...W.....,...
0x0000742f 0000 0000 f20f 1005 652b 1200 0f29 8330 ........e+...).0
0x0000743f 0900 0048 b800 0000 0000 00f0 bf48 8983 ...H.........H..
编辑:我忘了说表示是十六进制的。
我认为任何组都不会被替换,至少在我尝试时是这样。问题是 .{4,}
表示“至少四个字符”,但只有两个:\x60\xef
.
或者,如果您的输入确实是十六进制表示,请从代码中删除 \x
:在双引号中,\x60
表示字符 `
,而不是数字 6
和 0
。它们由 60
表示,没有任何前缀。
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
use Test::More;
my $in = "\x80\xbb\x60\xef\x00\x00\x00";
(my $out = $in) =~ s/(\x80\xbb)(.{2,})(\x00\x00\x00)/\xc6\x83\x00\x00\x01/g;
is $out, "\xc6\x83\x60\xef\x00\x00\x01";
my $in2 = '80bb60ef000000';
(my $out2 = $in2) =~ s/(80bb)(.{4,})(000000)/c683000001/g;
is $out2, 'c68360ef000001'; # ~~~~
注意 0
以防止将 0
解释为变量名称的一部分。
在代码中,您只保留两个连续字节进行替换,一个捕获组就足够了。
以下代码演示了如何将十六进制字符串转换为二进制值,进行必要的替换并将二进制输出为文本字符串。
use strict;
use warnings;
use feature 'say';
my($in,$out);
$out = $in = pack 'H*', '8100000080bb60ef00000075214c893c24488d1591ec12004c89ef4c89f648';
$out =~ s!\x80\xbb(.{2})\x00\x00\x00!\xc6\x83\x00\x00\x01!;
say 'in: ' . unpack('H*',$in);
say 'out: ' . unpack('H*',$out);
输出
in: 8100000080bb60ef00000075214c893c24488d1591ec12004c89ef4c89f648
out: 81000000c68360ef00000175214c893c24488d1591ec12004c89ef4c89f648