2012-08-10 115 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