我正在使用csv解析器类(http://code.google.com/p/php-csv-parser/)来解析和提取csv文件中的数据。我遇到的问题是它只适用于某些csv文件类型。 (对于Mac,Ms-Dos和Windows,似乎有一个csv类型。)
如果我使用csv-windows选项保存在mac(在excel中)的csv文件,代码可以正常工作。但是,如果我将文件保存在Windows机器上只是作为csv,那不起作用。 (您会认为这与在mac上保存csv-windows的格式相同。)如果我将其保存为csv-MSDOS文件,它可以在Windows机器上运行。这看起来有点荒谬。
有没有办法标准化这三种文件类型,以便我的代码可以读取上传的任何类型的csv?
我认为它会是这样的:
$standardizedCSV = preg_replace_all('/\r[^\n]/', '\r\n', $csvContent);
我知道它与每种文件类型处理行尾的方式有关,但是我试图弄清楚这些差异。如果有人有任何建议,请告诉我。
感谢。
更新: 这是我正在使用的csv解析器的相关代码,它逐行提取数据:
$c = 0;
$d = $this->settings['delimiter'];
$e = $this->settings['escape'];
$l = $this->settings['length'];
$res = fopen($this->_filename, 'r');
while ($keys = fgetcsv($res, $l, $d, $e)) {
if ($c == 0) {
$this->headers = $keys;
} else {
array_push($this->rows, $keys);
}
$c ++;
}
我想我需要了解fgetcsv如何处理eol,以便我可以确保以相同的方式处理任何格式的csv文件。
答案 0 :(得分:2)
这似乎可以解决问题:
ini_set("auto_detect_line_endings", true);
问题在于行结尾,但我不需要创建自己的EOL解析器。这个运行时设置适合我。请参阅http://us.php.net/manual/en/filesystem.configuration.php#ini.auto-detect-line-endings。
答案 1 :(得分:1)
我不认为行结尾是一个问题。关于CSV的事情是,它只是一个“逗号分隔值”文件,除此之外没有标准化。因此,一些系统使用逗号分隔值,一些使用分号(;
)。我确信有些变体甚至可以使用其他值分隔符。
此外,CSV文件之间的转义字符(通常是反斜杠\
)可能不同,而某些CSV文件也在每个值("
)周围使用引号。
CSV文件可以使用上述之间的任何变体。例如,我非常确定Microsoft Excel会导出CSV文件,这些文件使用分号分隔值,并且不会对值进行任何引用。
我确信有多种方法可以自动检测如何解析CSV文件,但最好的方法是让用户自行决定。这就是Excel所做的。
答案 2 :(得分:0)
如果您使用CSV文件,则必须就许多未正确标准化的细节达成一致:
如果您创建CSV阅读器,则可以自动处理行结尾和字段引用的不同变体。但其余部分必须事先为CSV解析器所知。
事实上的标准是Excel生成的CSV格式。但是,Excel使用不同的格式变体: