标准化CSV文件types

我正在使用csvparsing器类(http://code.google.com/p/php-csv-parser/)parsing和提取csv文件中的数据。 我遇到的问题是,它只适用于某些csv文件types。 (似乎有一个csvtypes的Mac,对于Ms-Dos和Windows。)

代码的作品,如果我使用csv文件保存在Mac(在Excel中)使用CSV – Windows选项。 但是,如果我将一个文件保存在Windows机器上,就像csv一样,那是行不通的。 (你可能会认为这与在Mac上保存csv-windows的格式是一样的。)如果我将它保存为csv-MSDOS文件,它可以在Windows机器上运行。 这似乎有点荒谬。

有没有办法来标准化这三种文件types,以便我的代码可以读取上传的任何types的csv?

我在想这将是这样的事情:

$standardizedCSV = preg_replace_all('/\r[^\n]/', '\r\n', $csvContent); 

我知道这与每个文件types如何处理行尾是有关系的,但是我有点努力弄清楚这些差异。 如果有人有任何build议,请让我知道。

谢谢。

更新:这是我使用的csvparsing器的相关代码,它逐行提取数据:

 $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文件都以相同的方式处理。

这似乎是诀窍:

  ini_set("auto_detect_line_endings", true); 

问题是线结束,但我不需要创build我自己的EOLparsing器。 这个运行时设置为我做。 请参阅http://us.php.net/manual/en/filesystem.configuration.php#ini.auto-detect-line-endings

我不认为行结局是一个问题。 关于CSV的事情是,它只是一个“逗号分隔值”文件,并没有超出这个标准。 所以有些系统使用逗号分隔这些值,有些使用分号( ; )。 我敢肯定,有些变化甚至使用其他价值分隔符。

另外,CSV文件中的转义字符(通常是反斜杠\ )可能不同,某些CSV文件也在每个值( " )周围使用引号。

一个CSV文件可以使用上述之间的任何变化。 例如,我相当肯定的是,Microsoft Excel导出的CSV文件使用分号分隔值,没有任何引号周围的值。

我确定有办法自动检测如何parsingCSV文件,但最好的方法是让用户来决定。 这就是Excel所做的。

如果您使用CSV文件,则必须同意很多未正确标准化的细节:

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

如果您创build了CSV阅读器,则可以自动处理线尾和字段引用的不同变体。 但其他的事先必须被CSVparsing器知道。

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

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