在Perl中解析多行数据

sfa*_*tor 1 perl split multiline text-parsing data-analysis

我有一些我需要分析的数据.数据是多行的,每个块由换行符分隔.所以,它是这样的

Property 1: 1234
Property 2: 34546
Property 3: ACBGD

Property 1: 1234
Property 4: 4567

Property 1: just
Property 3: an
Property 5: simple
Property 6: example
Run Code Online (Sandbox Code Playgroud)

我需要过滤掉那些存在某些特定属性的数据块.例如,只有具有属性4的那些,只有具有属性3和6的那些等等.我可能还需要根据这些属性的值进行选择,例如,只有具有属性3及其值的那些块是'一个'.

我将如何在Perl中执行此操作.我尝试用"\n"拆分它,但似乎没有正常工作.我错过了什么吗?

Dav*_*oss 14

使这项任务变得简单的秘诀是使用$ /变量将Perl置于"段落模式"中.这样可以轻松地一次处理一个记录.然后你可以用像grep这样的东西过滤它们.

#!/usr/bin/perl

use strict;
use warnings;

my @data = do {
  local $/ = '';
  <DATA>;
};

my @with_4   = grep { /^Property 4:/m } @data;

my @with_3   = grep { /^Property 3:/m } @data;
my @with_3_6 = grep { /^Property 6:/m } @with_3;

print scalar @with_3_6;

__DATA__
Property 1: 1234
Property 2: 34546
Property 3: ACBGD

Property 1: 1234
Property 4: 4567

Property 1: just
Property 3: an
Property 5: simple
Property 6: example
Run Code Online (Sandbox Code Playgroud)

在那个例子中,我将每个记录作为纯文本处理.对于更复杂的工作,我可能会将每条记录转换为哈希值.

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my @data;

{
  local $/ = '';

  while (<DATA>) {
    chomp;

    my @rec = split /\n/;
    my %prop;
    foreach my $r (@rec) {
      my ($k, $v) = split /:\s+/, $r;
      $prop{$k} = $v;
    }

    push @data, \%prop;
  }
}

my @with_4   = grep { exists $_->{'Property 4'} } @data;

my @with_3_6 = grep { exists $_->{'Property 3'} and
                      exists $_->{'Property 6'} } @data;

my @with_3an = grep { exists $_->{'Property 3'} and
                      $_->{'Property 3'} eq 'an' } @data;

print Dumper @with_3an;

__DATA__
Property 1: 1234
Property 2: 34546
Property 3: ACBGD

Property 1: 1234
Property 4: 4567

Property 1: just
Property 3: an
Property 5: simple
Property 6: example
Run Code Online (Sandbox Code Playgroud)

  • 对.您的数据结构几乎与我的相同.记录存储在一个数组中(因此它们保持原始顺序)但每个记录中的值都存储在一个哈希中,因此订单将丢失.这和我的解决方案完全一样.OP很清楚,在这种情况下,这些值的排序并不重要.他只是在询问是否可以在必要时保留订购.我们的两个解决方案都需要非常类似的改变来支持这一点. (2认同)