在Perl中,将CSV中的一行读取到散列中最具抗错性的方法是什么?
我想我可能遗漏了一些明显的东西,所以请告诉我 目前,我正在使用Text::CSV及其“parse”方法(如下所述)将一个CSV文件读入perl csv->解析方法:在Perl中,将CSV中的一行读取到散列中最具抗错性的方法是什么?,perl,csv,error-handling,cpan,Perl,Csv,Error Handling,Cpan,我想我可能遗漏了一些明显的东西,所以请告诉我 目前,我正在使用Text::CSV及其“parse”方法(如下所述)将一个CSV文件读入perl csv->解析方法: while (<FILE>) { if ($csv->parse($_)) { my @columns = $csv->fields(); 'refer to items with: $columns[1]' } else { 'Handle the parse er
while (<FILE>) {
if ($csv->parse($_)) {
my @columns = $csv->fields();
'refer to items with: $columns[1]'
}
else {
'Handle the parse error here'
}
}
my @cols = ("col1", "col2", "col3");
my $item = {};
$csv->bind_columns( \@{$item}{@cols} );
while( $csv->getline($it_fh) ) {
'refer to items using: $item->{col1}'
}
任何提示/提示/链接都很好,因为我的谷歌搜索结果似乎是空的
编辑:下面是我对我接受的答案的理解,只是为了澄清我对这种方法的容错性的理解
$csv->column_names( qw(col1 col2 col3) );
my $line;
until ( eof(FILE) ) {
$line++;
my $item = $csv->getline_hr( \*FILE );
if ( $item ) {
# refer to items as $item->{col1}
} else {
my $err = "Line: " . $line . "failed to parse\n"
. "Input: " . $csv->error_input . "\n"
. "Error: " . $csv->error_diag . "\n";
print STDERR $err;
}
}
你想要的。从其文档中:
use Text::CSV::Slurp;
my $data = Text::CSV::Slurp->load(file => $filename [,%options]);
my $data = Text::CSV::Slurp->load(filehandle => $filehandle [,%options]);
my $data = Text::CSV::Slurp->load(string => $string [,%options]);
$data现在是hashrefs的arrayref
编辑:我没有注意到问题的重点可能是错误处理。我认为它不会执行任何开箱即用的额外验证。您需要的。从其文档中:
use Text::CSV::Slurp;
my $data = Text::CSV::Slurp->load(file => $filename [,%options]);
my $data = Text::CSV::Slurp->load(filehandle => $filehandle [,%options]);
my $data = Text::CSV::Slurp->load(string => $string [,%options]);
$data现在是hashrefs的arrayref
编辑:我没有注意到问题的重点可能是错误处理。我认为它不会执行任何开箱即用的额外验证。好吧,总是有简单的方法:
my @cols = qw(col1 col2 col3);
while ( <FILE> ) {
if ( $csv->parse($_) ) {
my %item;
@item{@cols} = $csv->fields();
# refer to items using $item{col1}
}
else {
# handle the parse error here
}
}
好吧,总是有简单的方法:
my @cols = qw(col1 col2 col3);
while ( <FILE> ) {
if ( $csv->parse($_) ) {
my %item;
@item{@cols} = $csv->fields();
# refer to items using $item{col1}
}
else {
# handle the parse error here
}
}
正确使用is
正确使用is
干杯,伊尔马里,你的第二个例子正是我要找的那种东西,我只是不太明白如何把它们组合在一起。干杯,伊尔马里,你的第二个例子正是我要找的那种东西,我只是不太明白如何把它们组合在一起。我想我又错过了一些东西,以前发布的版本如何隐藏错误?您能详细说明一下吗?@Ashimema,从磁盘读取的大部分数据(如果不是全部的话)都是由Ilmari Karonen的代码中的
eof完成的,但是如果eof遇到错误,则不会进行错误检查。我不清楚如何检查错误。eof
是否在出错时返回false,然后在读取时返回错误?如果是,则不会隐藏任何错误。不过,这很复杂。为什么要过早地检查EOF(并引起这些问题),而不是让Text::CSV_XS告诉您它已经到达EOF?实际上,忽略推荐的方式会使代码变得更长。我现在明白你的意思了。。。如果我错了,请纠正我,但是您的实现不是一次只解析一行文件,然后在遇到问题行时就死掉了吗?我认为另一种方法也会一次一行解析一个文件,但如果一行失败但继续到下一行却没有死掉,则会报告错误?@ashimema,他可能试图这样做,但我们已经讨论过这是错误的。这就是你想要的吗?其次,一次一行解析一个文件通常是一个错误,因为一个字段可以跨越多行。我想我在这里又遗漏了一些东西,以前发布的版本是如何隐藏错误的?您能详细说明一下吗?@Ashimema,从磁盘读取的大部分数据(如果不是全部的话)都是由Ilmari Karonen的代码中的eof完成的,但是如果eof遇到错误,则不会进行错误检查。我不清楚如何检查错误。eof
是否在出错时返回false,然后在读取时返回错误?如果是,则不会隐藏任何错误。不过,这很复杂。为什么要过早地检查EOF(并引起这些问题),而不是让Text::CSV_XS告诉您它已经到达EOF?实际上,忽略推荐的方式会使代码变得更长。我现在明白你的意思了。。。如果我错了,请纠正我,但是您的实现不是一次只解析一行文件,然后在遇到问题行时就死掉了吗?我认为另一种方法也会一次一行解析一个文件,但如果一行失败但继续到下一行却没有死掉,则会报告错误?@ashimema,他可能试图这样做,但我们已经讨论过这是错误的。这就是你想要的吗?其次,一次一行解析一个文件通常是一个bug,因为一个字段可以跨越多行。
my $header = $csv->getline($fh)
or die("No header\n");
$csv->column_names(@$header);