我有以下问题。我有一个来自外部源的CSV文件,我正在尝试使用Text::CSV
模块以下列方式阅读它
$csv = Text::CSV->new({binary => 1}) or die "Could not open $filename : ".Text::CSV->error_diag();
binmode("stdout", ":utf8");
open $fh, "<encoding(utf8)", $filename or die "Could not open $filename : $!\n";
while ($row = $csv->getline($fh)) {
for ($i = 0; $i <= $#{$row}; $i++) {
$data = encode("utf8", $row->[$i]);
print "$data\n";
}
print "$row->[$keycol] => $row->[$valcol]\n";
$hash{$row->[$keycol]} = $row->[$valcol];
}
$csv->eof() or die " Error--- $i ".($csv->error_diag())."\n";
但是,在从该文件中读取几行后,程序会因错误而死亡。
在检查时,我发现数据中有列应该用引号" ... "
括起来,但只有一个引号在那里。而不是匹配的引号,那里有一个奇怪的^@
字符。如何用引号替换所有^@
个字符?它不是简单的ASCII,所以我不能$str =~ s/\^\@/\"/g
。
答案 0 :(得分:0)
^@
通常代表NUL
(ASCII 00
)。在Perl双引号和正则表达式文字中,它可以用\c@
,\0
,\x00
等表示
$str =~ s/\c@/"/g;
当大多数人试图删除NUL时,这是因为他们有未解码的UTF-16。解决方案实际上是执行适当的解码和编码。目前还不清楚这是你面临的问题。
答案 1 :(得分:-1)
我强烈建议您转到收到此文件的人,并要求他们提供一份他们没有在MS Word或其他任何地方编辑的副本。这听起来就像是你描述了一个被文字处理器蹂躏的文件,它相信一种更具装饰性的引号设置,并用#34倒置&替换其中一个。 #34;引号的版本。即,&#34;智能引号&#34;。
如果编辑对双引号这样做,那里的数据可能也会受到更多损坏。从理论上讲,您可以使用 s / \ x93 /&#34; / g 和 s / \ x94 /&#34; / g 还原它们,但他们当然可以应该从不首先使用CSV格式的文件。