读取带有不均匀逗号但固定列数的CSV文件

Kil*_*a.a -2 csv perl perl-data-structures

我希望能够将此CSV文件读入数组或散列数组以进行操作.我该怎么办呢?

例如,我的文件包含以下内容(第一行是标题):

Name,Age,Items,Available
John,29,laptop,mouse,Yes
Jane,28,desktop,keyboard,mouse,yes
Doe,56,tablet,keyboard,trackpad,touchpen,Yes
Run Code Online (Sandbox Code Playgroud)

第一列是名称,第二列是Age,第三列是Items,但是项目可以包含多个以逗号分隔的内容,最后一列是Person可用性.

我怎样才能准确读到这个?

Mic*_*man 5

格式良好的CSV引用包含逗号作为值的一部分的字段.如果您的CSV格式正确,请使用以下Text::CSV模块:

use Text::CSV;

my $csv = Text::CSV->new();
while (my $row = $csv->getline(\*DATA)) {
    my $name      = $row->[0];
    my $age       = $row->[1];
    my @items     = split /,/, $row->[2];
    my $available = $row->[3];
    print "$name/$age/@items/$available\n";
}

__DATA__
Name,Age,Items,Available
John,29,"laptop,mouse",Yes
Jane,28,"desktop,keyboard,mouse",yes
Doe,56,"tablet,keyboard,trackpad",touchpen,Yes
Run Code Online (Sandbox Code Playgroud)

输出:

Name/Age/Items/Available
John/29/laptop mouse/Yes
Jane/28/desktop keyboard mouse/yes
Doe/56/tablet keyboard trackpad touchpen/Yes
Run Code Online (Sandbox Code Playgroud)

如果您的CSV格式不正确,则需要根据您的数据知识实施自定义解析.假设Items列是唯一的多值字段,您可以在逗号上拆分,然后删除具有已知位置的字段.剩下的就是物品.

while (my $line = <DATA>) {
    chomp $line;
    my @record    = split /,/, $line;
    my $name      = shift @record;
    my $age       = shift @record;
    my $available = pop   @record;
    my @items     = @record;

    print "$name/$age/@items/$available\n";
}

__DATA__
Name,Age,Items,Available
John,29,laptop,mouse,Yes
Jane,28,desktop,keyboard,mouse,yes
Doe,56,tablet,keyboard,trackpad,touchpen,Yes
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用数组切片来获得相同的结果:

 my ($name, $age, $available, @items) = @record[0, 1, -1, 2 .. @record - 2];
Run Code Online (Sandbox Code Playgroud)

  • @ Kiluvya.a完全改变了事情.看起来你确实拥有一个结构良好的CSV,所以你应该使用一个合适的CSV解析器,如[Text :: CSV_XS](https://metacpan.org/pod/Text::CSV_XS).请注意,如果我们无法看到您的实际数据的代表性样本,我们可能无法提供最合适的解决方案.迈克尔的答案是你最初描述的问题的一个很好的解决方案,但显然这不是你遇到的实际问题. (3认同)
  • @ Kiluvya.a你的意思是有双引号?如果是这样,请编辑您的问题以显示您正在使用的实际数据的示例. (2认同)