如果您使用列表参数调用 push,则以堆栈方式将第一个列表与剩余列表附加在一起。在Perldoc 阅读有关推送的信息。所以你对push(@table, @row); 的调用是在创建一个更长的@table 列表,而不是一个二维数组。
您收到了几篇帖子,将@row 的列表引用推送为\@row 将创建一个行列表,这确实有效。我倾向于做一些不同的事情。当然,对于 Perl,总有另一种方法可以做到这一点!
在语法上,您还可以将匿名数组引用推送到列表的标量元素中以创建多维列表。关于 Perl 中的引用,最重要的一点是:1) 它们是标量,2) 它们可以引用 Perl 中的任何东西——代码、数组、散列、另一个引用。花一些时间使用Perl Ref Tutorial,这将变得更加清晰。使用您的代码,只需在您希望成为列表中第二维的元素周围添加[ ],因此push(@table, @row); 应该是push(@table, [ @row ]); 在同样的意义上,您将[ ] 放在您的拆分周围,使其变为@ 987654332@ 这将同时执行拆分并为结果创建一个匿名数组。
您遇到的具体问题,如何创建和访问多维列表,在 Tom Christensen 的perllol tutorial 中也得到了很好的处理,您的代码的具体问题的解决方案在这里直接处理。
使用 Tom 在 perllol 中的示例中的确切代码重写您的代码,它变成这样:
#!/usr/bin/perl
use strict;
use warnings;
my (@row, @table, $n, $rowref);
while(<DATA>) {
chomp;
# regex to separate CSV (use of a cpan module for CSV STRONGLY advised...
@row = /(?:^|,)("(?:[^"]+|"")*"|[^,]*)/g;
for (@row) {
if (s/^"//) { s/"$//; s/""/"/g; }
}
push(@table, [ @row ]); #Note the [ ] around the list
}
# Now the table is created, print it:
my $rowcnt=0;
foreach $rowref (@table) {
print "row $rowcnt:\n";
$rowcnt++;
print " [ @$rowref ], \n";
}
# You can access the table in the classic [i][j] form:
for my $i ( 0 .. $#table ) {
$rowref = $table[$i];
$n = @$rowref - 1;
for my $j ( 0 .. $n ) {
print "element $i, $j of table is $table[$i][$j]\n";
}
}
# You can format it:
for my $i ( 0 .. $#table ) {
print "$table[$i][0] $table[$i][1]\n";
print "$table[$i][2]\n";
print "$table[$i][3], $table[$i][4] $table[$i][5]\n\n";
}
__DATA__
Mac,Doe,120 jefferson st.,Riverside, NJ, 08075
Jack,McGinnis,220 hobo Av.,Phila, PA,09119
"John ""Da Man""",Repici,120 Jefferson St.,Riverside, NJ,08075
Stephen,Tyler,"7452 Terrace ""At the Plaza"" road",SomeTown,SD, 91234
,Blankman,,SomeTown, SD, 00298
"Joan ""Joan, the bone""",Jett,"9th, at Terrace plc",Desert City,CO,00123