使用 Text::CSV 在 Perl 中跳过错误的 CSV 行

Hes*_*sei 3 csv perl

我有一个基本上仍在测试中的脚本。我想使用 Text CSV 来分解每小时转储的大量 CSV 文件。

这些文件可能非常大并且质量不稳定。有时我会得到奇怪的字符或数据,但通常的问题是行停止。

"Something", "3", "hello wor
Run Code Online (Sandbox Code Playgroud)

封闭报价是我最大的障碍。剧本就这样被打破了。错误转到 stderr 并且我的 while 循环被破坏。

While (my $row = $csv->getline($data))
Run Code Online (Sandbox Code Playgroud)

我得到的错误是...

# CSV_PP ERROR: 2025 - EIQ - Loose unescaped escape
Run Code Online (Sandbox Code Playgroud)

我似乎无法为此进行任何类型的错误处理。如果我启用allow_loose_escapes,我得到的只是很多错误,因为它将后续的新行视为同一行的一部分。

TLP*_*TLP 5

允许松散的逃跑并不是答案。正如您也提到的,它只是使您的程序忽略错误并尝试将断线与其他行合并。相反,您可以尝试捕获问题,并检查您的$row定义:

use strict;
use warnings;
use Text::CSV;
use feature 'say';

my $csv = Text::CSV->new({
        binary  => 1,
        eol => $/,
    });

while (1) {
    my $row = $csv->getline(*DATA);
    $csv->eof and last; 
    if (defined $row) {
        $csv->print(*STDOUT, $row);
    } else {
        say "==" x 10;
        print "Bad line, skipping\n";
        say $csv->error_diag();
        say "==" x 10;
    }
}


__DATA__
1,2,3,4
a,b,c,d
"Something", "3", "hello wor
11,22,33,44
Run Code Online (Sandbox Code Playgroud)

对我来说这个输出:

1,2,3,4
a,b,c,d
====================
Bad line, skipping
2034EIF - Loose unescaped quote143
====================
11,22,33,44
Run Code Online (Sandbox Code Playgroud)

如果你想保存断线,你可以使用 来访问它们$csv->error_input(),例如:

print $badlines $csv->error_input();
Run Code Online (Sandbox Code Playgroud)

  • @Demnogonis 看来 Text::CSV 的 `eof` 与 Perl 的不同,因为它在读取行*之后*检查文件末尾,而不是之前。 (2认同)