从文件中读取不同长度的CSV-ish类型记录

时间:2014-01-08 19:08:39

标签: perl csv

该文件如下所示:

Nolan, Randall|(XYZ) {
  Bronco,
  Patient,
  New,
}
Tryor, Neil|(ABC) {
  Doyle,
  Agg,
}
Daniel, Liam|(ABC)
Taylor, Greg|(XYZ)

有关记录的注释:上面的最后两行是构成记录ID的内容,其格式为:Last_name,First_name |(CODE)。可选地,这些记录中的每一个可以具有一对括号。在这些括号内,将有一些用逗号分隔的项目,并将每个项目放在各自的行上,以便在查看文件时更好地进行布局。这些项之间的分隔符将保留为逗号。缺少任何此类项目将意味着在相应记录之后缺少任何括号(如上面的最后两个记录)。如果存在大括号,则意味着存在1到n个项目,其中n> = 1。 (示例中的前两个记录)

我想要做的就是抓住每个人,他们所有的信息并以这种方式处理:

  • 获取所有必填信息,即括号前的字段(保证在那里并由三个字段组成),并将其用作下一个内容的ID,这是在括号之间分组的项目
  • 大括号前的字段不能组合在一起,因此它们将分别分为:Last_name,First_name,Code。

问题是我不知道每个记录的大括号之间有多少项目我想在一些记录中使用所有字段进行一些进一步的处理我想从我从中提取的内容文件。

我想到的解决方案是有一个像这样的哈希数组:

my $records = [
    'First_Name' => 'Bob',
    'Last_Name' => 'Dolan',
    'Code' => 'XYZ',
    Items => [item1,
              item2,
              ... ]
    ]

所以这样我就可以在一个地方拥有我想要的所有数据,但是我需要遍历数据结构并以这种方式处理它。

这似乎是一个原始的解决方案。什么是一个更好的解决方案,我可以动态处理数据,因为我正在从文件中读取它,同时对可选的括号部分中的信息进行必要的检查和验证?

1 个答案:

答案 0 :(得分:1)

以下内容逐行读取数据,并将其存储在散列中。当到达记录的结尾时(行的末尾为)}),您可以处理哈希(我只需使用Data::Dumper打印)。

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my %record;
while (<DATA>) {
    chomp;

    # Assumes that none of the lines inside braces can contain "|"   
    if (/\|/) {
        my ($name, $code) = split /\|/;
        my ($last, $first) = split /,\s*/, $name;
        ($code) = ($code =~ /\((.*)\)/g);

        $record{first} = $first;
        $record{last} = $last;
        $record{code} = $code;
    }
    elsif (/,$/) {
        s/\s+//g;
        s/,//g;
        push @{ $record{items} }, $_;
    }

    # End of record, process it
    if (/[})]$/) {
        print Dumper(\%record);

        # Clear record after processing
        %record = ();
    }
}

__DATA__
Nolan, Randall|(XYZ) {
  Bronco,
  Patient,
  New,
}
Tryor, Neil|(ABC) {
  Doyle,
  Agg,
}
Daniel, Liam|(ABC)
Taylor, Greg|(XYZ)

输出:

$VAR1 = {
          'first' => 'Randall',
          'last' => 'Nolan',
          'code' => 'XYZ',
          'items' => [
                       'Bronco',
                       'Patient',
                       'New'
                     ]
        };
$VAR1 = {
          'first' => 'Neil',
          'last' => 'Tryor',
          'code' => 'ABC',
          'items' => [
                       'Doyle',
                       'Agg'
                     ]
        };
$VAR1 = {
          'first' => 'Liam',
          'last' => 'Daniel',
          'code' => 'ABC'
        };
$VAR1 = {
          'first' => 'Greg',
          'last' => 'Taylor',
          'code' => 'XYZ'
        };