标准化CSV文件类型

时间:2012-08-10 04:28:34

标签: php excel csv

我正在使用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文件。

3 个答案:

答案 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文件,则必须就许多未正确标准化的细节达成一致:

  • 行结尾(Unix 0x0a,Macintosh 0x0d,DOS 0x0d 0x0a)
  • 字段分隔符(逗号,分号等)
  • 字段引用(引用的所有字段,仅字符串字段,仅包含字段和行分隔符的字符串字段)
  • 在字符串字段中转义双引号(双引号加倍,双引号前反斜杠字符等)。
  • 多行字符串字段(是否允许)
  • 文件编码(ISO-8859-1,UTF-8等)

如果您创建CSV阅读器,则可以自动处理行结尾和字段引用的不同变体。但其余部分必须事先为CSV解析器所知。

事实上的标准是Excel生成的CSV格式。但是,Excel使用不同的格式变体:

  • 通常是DOS行结尾(但我从未尝试使用Excel for Macintosh)
  • 字段分隔符取决于区域设置。如果使用逗号分组长数字,Excel将分号用作字段分隔符。否则用逗号。
  • Excel根据需要使用双引号。
  • Excel将字符串字段中的双引号加倍。
  • Excel支持多行字符串字段。
  • 文件编码似乎是当前语言环境的文件编码。所以它会有所不同。