1. 程式人生 > >理解CSV格式規範(解析CSV必備)

理解CSV格式規範(解析CSV必備)

什麼是CSV

逗號分隔值(Comma-Separated Values,CSV),其檔案以純文字形式儲存表格資料(數字和文字),檔案的每一行都是一個數據記錄。每個記錄由一個或多個欄位組成,用逗號分隔。使用逗號作為欄位分隔符是此檔案格式的名稱的來源,因為分隔字元也可以不是逗號,有時也稱為字元分隔值。

CSV廣泛用於不同體系結構的應用程式之間交換資料表格資訊,解決不相容資料格式的互通問題,一般按照傳輸雙方既定標準進行格式定義,而其本身並無明確格式標準。

CSV用逗號分隔欄位的基本思想是清楚的,但是當欄位資料也可能包含逗號或者甚至嵌入換行符時,該想法變得複雜。 CSV實現可能無法處理這些欄位資料,或者可能會使用引號來包圍欄位。引用並不能解決所有問題:有些欄位可能需要嵌入引號,因此CSV實現可能包含轉義字元或轉義序列。

RFC 4180提出了MIME型別(”text/csv”)對於CSV格式的標準,可以作為一般使用的常用定義,滿足大多數實現似乎遵循的格式。

CSV的格式規範

下面的格式規範定義來源於RFC 4180,附上原文供參考,一共也就七點。

1. 每一行記錄位於一個單獨的行上,用回車換行符CRLF(也就是\r\n)分割。

Each record is located on a separate line, delimited by a line break (CRLF). For example:

aaa,bbb,ccc CRLF
zzz,yyy,xxx CRLF

2. 檔案中的最後一行記錄可以有結尾回車換行符,也可以沒有。

The last record in the file may or may not have an ending line break. For example:

aaa,bbb,ccc CRLF
zzz,yyy,xxx

3. 第一行可以存在一個可選的標題頭,格式和普通記錄行的格式一樣。標題頭要包含檔案記錄欄位對應的名稱,應該有和記錄欄位一樣的數量。(在MIME型別中,標題頭行的存在與否可以通過MIME type中的可選”header”引數指明)

There maybe an optional header line appearing as the first line of the file with the same format as normal record lines. This header will contain names corresponding to the fields in the file and should contain the same number of fields as the records in the rest of the file (the presence or absence of the header line should be indicated via the optional “header” parameter of this MIME type). For example:

field_name,field_name,field_name CRLF
aaa,bbb,ccc CRLF
zzz,yyy,xxx CRLF

4. 在標題頭行和普通行每行記錄中,會存在一個或多個由半形逗號(,)分隔的欄位。整個檔案中每行應包含相同數量的欄位,空格也是欄位的一部分,不應被忽略。每一行記錄最後一個欄位後不能跟逗號。(通常用逗號分隔,也有其他字元分隔的CSV,需事先約定)

Within the header and each record, there may be one or more fields, separated by commas. Each line should contain the same number of fields throughout the file. Spaces are considered part of a field and should not be ignored. The last field in the record must not be followed by a comma. For example:

aaa,bbb,ccc

5. 每個欄位可用也可不用半形雙引號(“)括起來(不過有些程式,如Microsoft的Excel就根本不用雙引號)。如果欄位沒有用引號括起來,那麼該欄位內部不能出現雙引號字元。

Each field may or may not be enclosed in double quotes (however some programs, such as Microsoft Excel, do not use double quotes at all). If fields are not enclosed with double quotes, then double quotes may not appear inside the fields. For example:

"aaa","bbb","ccc" CRLF
zzz,yyy,xxx

6. 欄位中若包含回車換行符、雙引號或者逗號,該欄位需要用雙引號括起來。

Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes. For example:(下面原文的例子可能有些問題)

"aaa","b CRLF
bb","ccc" CRLF
zzz,yyy,xxx

7. 如果用雙引號括欄位,那麼出現在欄位內的雙引號前必須加一個雙引號進行轉義。

If double-quotes are used to enclose fields, then a double-quote appearing inside a field must be escaped by preceding it with another double quote. For example:

"aaa","b""bb","ccc"

關於CSV檔案解析

上面說過,CSV並不是一種單一的、定義明確的格式(儘管RFC 4180有一個被通常使用的定義)。因此在實踐中,術語“CSV”泛指具有以下特徵的任何檔案:

  • 純文字,使用某個字符集,比如ASCII、Unicode、EBCDIC或GB2312;
  • 由記錄組成(典型的是每行一條記錄);
  • 每條記錄被分隔符分隔為欄位(典型分隔符有逗號、分號或製表符;有時分隔符可以包括可選的空格);
  • 每條記錄都有同樣的欄位序列。

所以,在常規的約束條件下,存在著許多CSV變體,故CSV檔案並不完全互通,如使用約定好的其他分隔符、轉義規則等。因此,實際使用CSV需要資料交換雙方約定規則(其實大體思路不變,一些細節),在進行CSV檔案讀寫就免不了進行檔案的解析。

正如CSV並不明確的格式,CSV檔案的解析同樣沒有標準方法,一般可以自己實現讀寫,網上也有很多種不同語言的實現版本。例如opencsv、csvreader等。它們可能會與RFC中的規定有所出入,例如在csvreader中有要求:

字首和字尾的空格字元,逗號和製表符,與逗號或記錄分隔符相鄰的內容將被修剪。
為了保證前導和字尾空白字元的保留,必須通過將欄位嵌入到雙引號集合中來限定欄位。

使用時需要注意。