2012-08-10 44 views
3

我正在使用csv解析器类(http://code.google.com/p/php-csv-parser/)解析并从csv文件中提取数据。我遇到的问题是它只适用于某些csv文件类型。 (似乎有一个csv类型的Mac,为Ms-Dos和Windows。)标准化CSV文件类型

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

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

我想它会是这样的:

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

我知道它是与每个文件类型如何处理行的结束,但我有点放出来试图图那些差异。如果有人有任何建议,请告诉我。

谢谢。

UPDATE: 这是我使用的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

更新我将csv解析器中的相关代码添加到原始文章中,以便您可以看到它如何处理EOL。 – user1383418 2012-08-10 04:57:00

回答

1

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

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

CSV文件可以使用上述之间的任何变化。例如,我很确定Microsoft Excel导出的CSV文件使用分号分隔值,并且没有引用任何值。

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

+0

我认为EOL的问题的原因是,当我的解析器运行一个不兼容的cvs类型(如上所述)时,$ csvparser-> headers变量记录了整个文件 - 它不仅记录第一排。合规的csv类型非常整洁地将标题存储在$ this->标题和$ this->行的数据行中。因此,某种文件类型的EOL会以某种方式导致while循环迭代,而其他文件则不会。 – user1383418 2012-08-10 05:47:16

+0

另外 - 当我在文本编辑器中并排查看兼容的和不兼容的csv文件类型时,它们与用逗号分隔值完全相同。 (我正在使用BBEdit来做到这一点。)两者之间的唯一区别是BBEdit指出兼容版本是'Windows(CRLF)'格式 - (这是在BBEdit窗口底部的下拉菜单中,我可以't'see'the EOLs but .. – user1383418 2012-08-10 05:56:35

0

如果使用CSV文件,您必须对许多细节达成一致的看法是不正确的规范:

  • 行结束符(Unix的0X0A,苹果0X0D,DOS 0X0D 0X0A)
  • 字段分隔符(逗号,分号等)
  • 字段引用(所有字段引用,只有字符串字段,只有包含字段和行分隔符)
  • 逃逸字符串字段内双引号(双引号的倍增,反斜线字符之前双引号等字符串字段)
  • 多行字符串字段(是他们允许与否)
  • 文件编码(ISO-8859-1,UTF-8等)

如果你创建一个CSV阅读器,可以自动处理不同行结尾的变化和字段引用。但其余的必须事先知道CSV解析器。

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

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

谢谢你的详细回复。我没有标准化行结束以符合DOS格式 - 0x0d 0x0a - 这适用于一个文件,但不适用于另一个文件。以不同的方式查看该文件是否可能不符合规范 - 它可能使用冒号而不是逗号来描述信息,例如,我会在早上看看,并报告回来,非常感谢。 – user1383418 2012-08-10 06:15:22