根据随机 header 布局 perl 解析 CSV

Parse CSV based on random header layout perl

我正在使用 Tie::Handle::CSV 尝试一些代码,但是我想这完全可以使用其他模块或 none 来完成。

我想要做的是获取一个随机布局的文件,并将其与我预测的 headers 相匹配。然后我想把它安排到我的table结构中。

数据

名字、姓氏、出生日期
吉姆·约翰森,1989 年 8 月 25 日

第二个名字,第一个名字,D.O.B
约翰森,吉姆,1989 年 8 月 25 日

第二个名字,第一个名字,D.O.B,城市,县
约翰森,吉姆,1989 年 8 月 25 日,密尔沃基,N/A

如您所见,我有不同的数据结构。我希望它将它们安排到我的模式中,即使我请求的字段是空的。我想要执行此操作的方法是使用我的列变量搜索我的输入。

这是我正在尝试的。

代码

use Tie::Handle::CSV;
my $name1 =qr/First Name|Name|1st Name/i;
my $name2 =qr/Last Name|Maiden Name|2nd Name/i;
my $date_of_birth =qr/date of birth|D.O.B/i;
my $city =qr/city|town/i;
   my $csv_fh = Tie::Handle::CSV->new('list.txt', header => 1);
   while (my $csv_line = <$csv_fh>)
      {
      print $csv_line->{'$date_of_birth'}.",".$csv_line->{'$name1'}." ".$csv_line->{'$name2'}.",".$csv_line->{'$city'}.\n";  ##note I am searching for the column {$'colummn regex'} instead of {'column'} to see if my input file matches any of the header options.
      }
   close $csv_fh;

我的输出是空白的,因为这个模块不理解我正在使用的正则表达式。但是,如果我使用它们的文字名称,我的输出将包含指定的列,即

我想要的输出是:

场景一

出生日期、姓名、城市##我实施了header
1989 年 8 月 25 日,Jim Johansen,## 还注意到如果输入数据中没有 'city',请留空。

场景二

出生日期、姓名、城市##我实施了header
1989 年 8 月 25 日,吉姆·约翰森,

场景三 出生日期、姓名、城市 ##my 实施 header
1989 年 8 月 25 日,吉姆·约翰森,密尔沃基

也许有比模块甚至我的正则表达式变量更好的选择。有没有人必须在不断变化的布局中解析 csvs?

您从不使用 $name1$name2 等,更不用说在匹配(或替换)运算符中,因此您永远不会执行任何正则表达式匹配。

my $field_names = $csv_fh->header();

my ($name1_header) = grep /First Name|^Name$|1st Name/i,     @$field_names;
my ($name2_header) = grep /Last Name|Maiden Name|2nd Name/i, @$field_names;
my ($dob_header  ) = grep /date of birth|D\.O\.B/i,          @$field_names;
my ($city_header ) = grep /city|town/i,                      @$field_names;

my @recognized_fields = ( $name1_header, $name2_header, $dob_header, $city_header );
my %recognized_fields = map { $_ => 1 } @recognized_fields;
my @other_headers = grep !$recognized_fields{$_}, @$field_names;

while (my $row = <$csv_fh>) {
   my $name1 = $name1_header ? $row->{$name1_header} : undef;
   my $name2 = $name2_header ? $row->{$name2_header} : undef;
   my $dob   = $dob_header   ? $row->{$dob_header  } : undef;
   my $city  = $city_header  ? $row->{$city_header } : undef;

   my @other_fields = @$row{@other_headers};

   ...
}