Perl - CSV中的正则表达式

时间:2013-08-05 20:58:51

标签: regex perl csv delimiter substitution

以下问题:

我有一个分隔文件,哪些行有25或26个字段。 对于有25个字段的所有行,我需要在第13个字段后面添加一个空行,这样它就会有26个字段。

旧:

Z|432651242|987654321|XYZ|Abc|DEFEF||Abc-De-Fg|18|33221|Qwerty|18.06.3213|abc||123|Tepp|11.07.4443|2|||||4433322342344||

新:

Z|432651242|987654321|XYZ|Abc|DEFEF||Abc-De-Fg|18|33221|Qwerty|18.06.3213|abc|||123|Tepp|11.07.4443|2|||||4433322342344||

我设法过滤了需要更改的行:

#!/usr/bin/perl
use strict;
use warnings;

my (@cols,$fieldLength,);
while(<>){
  @cols = split('\|', $_);
  $fieldLength=@cols;
  if ($fieldLength==25){
  print $_;
  }
}

我的想法是用分隔符替换“|”在第13次出现“||”,但无法设法这样做。我试图谷歌,但这些例子对我不起作用。

有人可以帮我吗?

我也很感激使用CPAN的CSV模块解决方案。

2 个答案:

答案 0 :(得分:1)

您可以使用Text::CSV来解析线条,使用拼接插入空行并将其打印出来。这样的事情应该有效:

use strict;
use warnings;
use Text::CSV;

my $csv = Text::CSV->new({
    sep_char => '|',
    eol      => $/,
});

while (my $row = $csv->getline(*ARGV)) {
    splice(@$row, 12, 0, '') if @$row == 25;
    $csv->print(*STDOUT, $row);
}

答案 1 :(得分:1)

如果您可以放心地假定分隔符|从未出现在字段数据中,那么您可以使用splitsplice,但Text::CSV更安全。

#!/usr/bin/perl
use strict;
use warnings;

while (<>)
{
    my @cols = split /[|]/;
    if (scalar(@cols) == 25)
    {
        splice(@cols, 13, 0, '');
        $_ = join('|', @cols);
    }
    print;
}

这似乎产生了您想要的输出。给定输入文件:

Z|432651242|987654321|XYZ|Abc|DEFEF||Abc-De-Fg|18|33221|Qwerty|18.06.3213|abc||123|Tepp|11.07.4443|2|||||4433322342344||
Z|432651242|987654321|XYZ|Abc|DEFEF||Abc-De-Fg|18|33221|Qwerty|18.06.3213|abc|def|123|Tepp|11.07.4443|2|||||4433322342344||

(其中第二行有def代替空字段,因此您可以确切地看到插入的位置),输出为:

Z|432651242|987654321|XYZ|Abc|DEFEF||Abc-De-Fg|18|33221|Qwerty|18.06.3213|abc|||123|Tepp|11.07.4443|2|||||4433322342344||
Z|432651242|987654321|XYZ|Abc|DEFEF||Abc-De-Fg|18|33221|Qwerty|18.06.3213|abc||def|123|Tepp|11.07.4443|2|||||4433322342344||
相关问题