如何在perl中以相同的字符串开头和结尾两行之间提取内容?

时间:2016-03-17 13:38:36

标签: perl

数据文件包含以下内容

 7e a1 00 00 00 00 00 00  00 00 00 05 00 00 00
 ea 5b ee fb 7e 7e a1 01  00 00 00 00 00 00 00
 05 00 00 00 c0 9c ba e1  66 7e 7e a1 02 00 00
 00 00 00 00 00 05 00 00  00 c0 47 9f 80 1a 7e

当我尝试在第1个7e到第2个7e之间以及从第3个7e到第4个7e之间连续打印时,其中我的预期输出如下,不包括引用自开始和结束以来每行'7e'都是相同的,传统方法不起作用。

 `7e` a1 00 00 00 00 00 00 00 00 00 00 05 00 00 00 ea 5b ee fb `7e` 
 `7e` a1 01 00 00 00 00 00 00 00 00 05 00 00 00 c0 9c ba e1 66 `7e`
 `7e` a1 02 00 00 00 00 00 00 00 00 05 00 00 00 c0 47 9f 80 1a `7e`

我已尝试使用以下初始perl,但结果不符合预期,任何人都可以澄清我的理解,我已尝试过以下内容,

    use strict;
    use warnings;
    my $filename = 'input_file.txt';
    open(my $fh, '<:encoding(UTF-8)', $filename)
      or die "Could not open file '$filename' $!";
    my $count=0;
    while (<$fh>) {
      if (/7e/../7e/) {
        next if /7e/ || /7e/;
        print;
      }
    }

还需要检查7e的每个偶数末尾,即第2个,第4个等等。下一个开始应该是7e,否则应该标记错误。

2 个答案:

答案 0 :(得分:2)

这看起来像十六进制转储,这会使7e代表~。您确定解析十六进制转储是您想要做的吗?

您的代码存在的问题是您的数据跨越行结尾,并且您正在逐行模式下读取文件。此外,您正在跳过包含7e的行,这意味着您从某些行中删除了内容。

使用记录输入分隔符可能最简单,并将其设置为7e。这表示您正在阅读以字符串7e结尾的行,而不是\n

我也在使用计数器来跳过奇数行。我正在使用Data::Dumper以更易读的方式显示数据。

use strict;
use warnings;
use Data::Dumper;

$/ = '7e';
my $count;
my @data;
while (<DATA>) {
    chomp;
    if ($count++ % 2) {
        push @data, $_;
    } else {
        warn "Data in wrong place ('$_')" if /\S/;
    }
}
print Dumper \@data;

__DATA__
 7e a1 00 00 00 00 00 00  00 00 00 05 00 00 00
 ea 5b ee fb 7e 7e a1 01  00 00 00 00 00 00 00
 05 00 00 00 c0 9c ba e1  66 7e 7e a1 02 00 00
 00 00 00 00 00 05 00 00  00 c0 47 9f 80 1a 7e

<强>输出:

$VAR1 = [
          ' a1 00 00 00 00 00 00  00 00 00 05 00 00 00
 ea 5b ee fb ',
          ' a1 01  00 00 00 00 00 00 00
 05 00 00 00 c0 9c ba e1  66 ',
          ' a1 02 00 00
 00 00 00 00 00 05 00 00  00 c0 47 9f 80 1a '
        ];

答案 1 :(得分:1)

您的问题很大一部分是数据跨行分割。你真的需要单独处理每个字节

此进程读取整个转储并将所有数据放入$data中的单行,并在字节之间留出一个空格。然后一个简单的全局正则表达式模式找到你想要的所有子序列

use strict;
use warnings 'all';
use feature 'say';

local $/;
my $data = join ' ', split ' ', <DATA>;

say $1 while $data =~ /7e\s(.+?)\s7e/g;

__DATA__
 7e a1 00 00 00 00 00 00  00 00 00 05 00 00 00
 ea 5b ee fb 7e 7e a1 01  00 00 00 00 00 00 00
 05 00 00 00 c0 9c ba e1  66 7e 7e a1 02 00 00
 00 00 00 00 00 05 00 00  00 c0 47 9f 80 1a 7e

输出

a1 00 00 00 00 00 00 00 00 00 05 00 00 00 ea 5b ee fb
a1 01 00 00 00 00 00 00 00 05 00 00 00 c0 9c ba e1 66
a1 02 00 00 00 00 00 00 00 05 00 00 00 c0 47 9f 80 1a
相关问题