逗號分隔值

文文格式

逗號分隔值(Comma-Separated Values,CSV,有時也稱為字符分隔值,因為分隔字符也可以不是逗號),其文件以純文本形式存儲表格數據(數字和文本)。純文本意味着該文件是一個字符序列,不含必須像二進制數字那樣被解讀的數據。CSV文件由任意數目的記錄組成,記錄間以某種換行符分隔;每條記錄由字段組成,字段間的分隔符是其它字符或字符串,最常見的是逗號或制表符。通常,所有記錄都有完全相同的字段序列。

逗號分隔值
逗號分隔列
副檔名
.csv.txt
網路媒體型式
text/csv
格式類型跨平台,串行數據流
作為容器數據庫按字段分隔的列表的信息組織
標準RFC 4180

CSV文件的格式不存在通用標準,也沒有指定所使用的字符編碼,但是在RFC 4180中有基礎性的描述, 而7-bit ASCII是最基本的通用編碼。

用法

CSV是一種通用的、相對簡單的文件格式,被用戶、商業和科學廣泛應用。最廣泛的應用是在程序之間轉移表格數據,而這些程序本身是在不兼容的格式上進行操作的(往往是私有的英語Proprietary format和/或無規範的格式)。因為大量程序都支持某種CSV變體,至少是作為一種可選擇的輸入/輸出格式。

例如,一個用戶可能需要交換信息,從一個以私有格式存儲數據的數據庫程序,到一個數據格式完全不同的電子表格。最可能的情況是,該數據庫程序可以導出數據為「CSV」,然後被導出的CSV文件可以被電子表格程序導入。

「CSV」不是一種單一的、定義明確的格式(儘管RFC 4180有一個被廣泛使用的定義),因此在實踐中,術語「CSV」泛指具有下列特徵的任何文件:

  1. 純文本,使用某個字符集,比如ASCIIUnicodeEBCDICGB2312(簡體中文環境)等;
  2. 記錄組成(典型的是每行一條記錄);
  3. 每條記錄被分隔符英語Delimiter分隔為字段(典型分隔符有逗號、分號或制表符;有時分隔符可以包括可選的空格);
  4. 每條記錄都有同樣的字段序列。

在這些常規的約束條件下,存在着許多CSV變體,故CSV文件不完全兼容。然而,這些差異非常小,而且有許多應用程序可以讓用戶預覽文件(這是可行的,因為它是純文本),甚至指定分隔符、轉義規則等。如果一個特定CSV文件的差異過大,超出了特定接收程序的支持範圍,那麼可行的做法通常是人工檢查並編輯文件,或通過簡單的程序來修復問題。

歷史

逗號分隔值是一種數據格式,列表方式(「自由形式」)輸入/輸出被定義在FORTRAN 77(77代表1977年)中。列表方式的輸入使用了逗號和/或空格作為分隔符,所以用來結束引文的字符串不能包含逗號或空格。[1]

相對於固定列寬數據格式,逗號分隔值的列表不僅輸入(例如輸入到打孔卡)更加方便,而且當一個值被錯打一列時也不容易產生錯誤結果。

逗號分隔列(CSL)是一種數據格式,起初在最古老的簡單電腦中被稱為逗號分隔值(CSV)。在個人電腦(當時更普遍地被稱為「家用電腦」)產業,一個常見的應用是,小企業使用模板郵件列表生成推銷郵件。[來源請求]

CSL/CSV被用來作為簡單的數據庫。一些早期的軟件應用,比如文字處理器,允許一系列「變量數據」在兩個文件之間被合併:一個是模板文件,一個是包含姓名、地址和其它數據字段的CSL數據庫。許多應用程序仍然有這種能力。[2]

逗號分隔列過去和現在都被用於在兩個不同架構的機器之間交換數據庫信息。純文本的CSV文件大幅避免了不兼容性,比如字節順序字長。這些文件大部分是可讀的,所以在沒有完美的文檔或通訊的情況下仍然很容易處理。

常規功能

CSV格式最好被用來表現記錄集合或序列,其中的每條記錄都有完全相同的字段序列。這相當於關係數據庫中一個單一的關係,或者典型的電子表格中的數據(雖然不能計算)。

CSV格式沒有被限定於某個特定字符集。不管用Unicode還是用ASCII,都沒有問題(儘管特定程序支持的CSV可能會有它們自己的局限性)。和大部分的私有數據格式不同,CSV文件可以從一個字符集翻譯到另外一個字符集。然而,CSV不提供任何途徑來表明使用的是什麼字符集,所以必須另外通訊,或在接收結束時指出(如果可能)。

如前所述,包含多個關係的數據庫不能導出為單一的CSV文件。最多,只能添加更多的標識約定,例如標識和分隔不同的關係。這種標識並不難於設計和實現,但是因為沒有這方面的約定,所以基本不具備可移植性。

同樣地,CSV本身不能表達分層級的或面向對象的數據庫或其它數據。這是因為每一條CSV記錄都應當有同樣的結構。CSV因此基本不適用於文檔,比如由HTMLXML或者其它的標記語言或文字處理技術創建的。

字段會變化的統計數據庫往往有着類似關係的結構,但是會有一些字段組是可重複的。例如,健康數據庫如人口與健康調查英語Demographic and Health Surveys,對於一名給定的父母會為每個孩子重複一些問題(也許直到某個確定的最大的孩子數目)。統計分析系統往往包含可以「旋轉」這類數據的工具:例如,一條包含5個孩子信息的「父母」記錄,可以被分解為5條單獨的記錄,每條記錄包含(a)一個孩子的信息,和(b)一份所有未指定孩子的信息的拷貝。CSV可以用「橫的」或「豎的」形式來表達這類數據。

在關係數據庫中,類似的問題很容易解決——為每個類似的組另外創建一個關係,並使用外鍵(如父母的身份證號或名字)將「孩子」記錄與相關的「父母」記錄連接起來。在標記語言如XML中,這類組會被包含在一個容器中(例如,<child>),然後按照需要重複該容器。對於CSV,則尚無被廣泛接受的單文件解決方案。

缺乏規範

「CSV」這個名字表示是用逗號來分隔數據字段的。然而,「CSV」這個術語還被廣泛用於形式各異的一系列格式。例如,許多所謂的「CSV」文件實際上使用制表符代替逗號(這種文件可以更精確地被稱為「TSV」,即制表符分隔值,Tab-Separated Values);一些實現允許或要求使用單引號或雙引號來包裹某些或全部字段;還有一些實現保留最前面的一條記錄作為表頭來包含字段名序列。

其它的實現差別包括如何處理更多常見的字段分隔符(比如空格或分號[3])和在文本字段中的換行符。[4]更加微妙的是對一個空行的翻譯:寫一條零字段的記錄,或者一條有一個零長度字段的記錄同樣可以得到這樣的結果;因此對它的解碼是有歧義的——只不過這種歧義通常無傷大雅。

RFC 4180所記載的標準可以使CSV交換簡單化。然而,這一標準僅指定了對基於文本的字段的處理。對各個字段的文本的翻譯仍然是由引用程序指定的。特別地,並沒有標準來指定如何表示小數,儘管它們普遍被嵌入在CSV數據中,並且一些國家使用點作為小數分隔符,一些國家使用逗號。例如,法文CSV文件可能將圓周率的近似值寫為3,14159。

一個通用的(如果技術上不令人滿意)互操作性解決方案是依賴人工介入:因為CSV文件是純文本,用戶可以通過使用文本編輯器輕易預覽和診斷絕大部分(如果不是全部)問題。這樣做的例子包括 Microsoft Access 等(關係)數據庫產品,其在導入 CSV/TSV 這種數據時便允許用戶一邊預覽一邊調整諸如表頭行、分隔符之類的選項。

進行中的標準化

「CSV」格式中大量變體的存在說明並沒有一個「CSV標準」。[5][6]在常見用法中,幾乎任何定界符分隔的文本數據英語Delimiter-separated values都可以被統稱為「CSV」文件。不同的CSV格式可能不會兼容。

不過,RFC 4180是一個將CSV正式化的努力。它定義了互聯網媒體類型「text/csv」,並且採用它的規則的CSV文件將會具有廣泛的可移植性。它有如下要求:

  • 以(CR/LF)字符結束的DOS風格的行(最後一行可選)。
  • 一條可選的表頭記錄(沒有可靠的方式來檢測它是否存在,所以導入時必須謹慎)。
  • 每條記錄「應當」包含同樣數量的逗號分隔字段。
  • 任何字段都可以被包裹(用雙引號)。
  • 包含換行符、雙引號和/或逗號的字段應當被包裹。(否則,文件很可能不能被正確處理)。
  • 字段中的一個(雙)引號字符必須被表示為兩個(雙)引號字符。

這個格式很簡單,可以被大部分聲稱可以讀取CSV文件的程序處理。例外是(a)程序可以不支持在被包裹的字段中換行,(b)程序可以將可選的表頭當作數據,或者將第一個數據行當作可選的表頭。

技術背景

該格式可以追溯至早期的商用電腦,它被廣泛用於在電腦間傳遞數據,這些電腦可能會有不同的內在字長,需要不同的數據格式,等等。為此,CSV文件在所有電腦平台上通用。

CSV是一種分隔的英語Delimiter-separated values文本文件,它使用逗號來分割值(許多CSV導入/導出工具的實現也允許使用其它的分隔符)。簡單的CSV實現可以禁止字段值中包含逗號或其它特殊字符如換行符。更複雜的CSV實現允許這些特殊字符,它們往往要求用"(雙引號)包裹這些包含保留字符(如逗號、雙引號或不太通用的換行符)的數值。被嵌入的雙引號字符可以用連續兩個雙引號來表示(Creativyst 2010),或者使用轉義字符反斜槓(例如在Sybase Central中)。

在計算機科學術語中,CSV文件可以被認為是一個「平面文件數據庫」。

基本規則及舉例

存在許多描述「CSV」格式的非正式文件。IETF RFC 4180(如上所述)定義了格式「text/csv」互聯網媒體類型,並已註冊於IANA。(Shafranovich 2005)另一個相關規範由含字段文本英語Fielded text提供。Creativyst (2010)提供了一個概述,說明了在最廣泛使用的應用程序中所使用的變體,並解釋了CSV怎樣才能最好地被使用和支持。

這些和其它「CSV」規範及實現的典型規則如下:

  • CSV文件不要求特定的字符編碼字節序或行結束符格式(某些軟件不支持所有行結束變體)。
  • 一條記錄結束於行結束符。然而,行結束符可能被作為數據嵌入到字段中,所以軟件必須識別被包裹的行結束符(見下述),以便從可能的多行中正確組裝一條完整的記錄。
  • 所有記錄應當有相同數目、相同順序的字段。
  • 字段中的數據被翻譯為一系列字符,而不是一系列比特或字節(見RFC 2046,section 4.1)。例如,數值量65535可以被表現為5個ASCII字符「65535」(或其它形式如「0xFFFF」、「000065535.000E+00」等等);但不會被作為單個二進制整數的2字節序列(而非兩個字符)來處理。如果不遵循這個「純文本」的慣例,那麼該CSV文件就不能包含足夠的信息來正確地翻譯它,該CSV文件將不大可能在不同的電腦架構間正確傳遞,並且將不能與text/csv MIME類型保持一致。
  • 相鄰字段必須被單個逗號分隔開。然而,「CSV」格式在分隔字符的選擇上變化很大。特別是在某些區域設置中逗號被用作小數點,則會使用分號、制表符或其它字符來代替。
1997,Ford,E350
  • 任何字段都可以包裹(使用雙引號字符)。某些字段必須被包裹,詳見後續規則。
"1997","Ford","E350"
  • 如果字段包含被嵌入的逗號,必須被包裹。
1997,Ford,E350,"Super, luxurious truck"
  • 每個被嵌入的雙引號字符必須被表示為兩個雙引號字符。
1997,Ford,E350,"Super, ""luxurious"" truck"
  • 如果字段包含被嵌入的換行,必須被包裹(然而,許多簡單的CSV實現不支持字段內換行)。
1997,Ford,E350,"Go get one now
they are going fast"
  • 在某些CSV實現中,起頭和結尾的空格和制表符被截掉。這一實踐是有爭議的,也不符合RFC 4180。RFC 4180聲明「空格被看作字段的一部分,不應當被忽略。」
1997, Ford, E350
not same as
1997,Ford,E350
  • 然而,該RFC並沒有說當空白字符出現在被包裹的值之外該如何處理。
1997, "Ford" ,E350
  • 在截掉起頭和結尾空格的CSV實現中,將這種空格視為有意義數據的字段必須被包裹。
1997,Ford,E350," Super luxurious truck "
  • 第一條記錄可以是「表頭」,它在每個字段中包含列名(並沒有可靠途徑來告知一個文件是否這樣包含表頭;然而,一般在列名中僅使用字母、數字和下劃線,而不使用其它字符)。
Year,Make,Model
1997,Ford,E350
2000,Mercury,Cougar

舉例

年份 品牌 型號 描述 價格
1997 Ford E350 ac, abs, moon 3000.00
1999 Chevy Venture "Extended Edition" 4900.00
1999 Chevy Venture "Extended Edition, Very Large" 5000.00
1996 Jeep Grand Cherokee MUST SELL!
air, moon roof, loaded
4799.00

以上數據表可以以CSV格式表示如下:

Year,Make,Model,Description,Price
1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture ""Extended Edition""","",4900.00
1999,Chevy,"Venture ""Extended Edition, Very Large""",,5000.00
1996,Jeep,Grand Cherokee,"MUST SELL!
air, moon roof, loaded",4799.00

美國/英國的CSV文件(小數點是點,值分隔符是逗號)舉例:

Year,Make,Model,Length
1997,Ford,E350,2.34
2000,Mercury,Cougar,2.38

德國和荷蘭同樣的CSV/DSV英語Delimiter separated values文件(小數點是逗號,值分隔符是分號)舉例:

Year;Make;Model;Length
1997;Ford;E350;2,34
2000;Mercury;Cougar;2,38

後者的格式是不遵循RFC 4180的。若要使它遵循,可以使用逗號代替分號作為分隔符,或者使用小數點表示法的國際符號,或者包裹所有包含小數點的數字。

應用程序支持

CSV文件格式非常簡單,被幾乎所有的電子表格數據庫管理系統支持。許多編程語言都有可利用的庫來支持CSV文件。許多實現都支持變換字段分隔字符和一些包裹約定以最大化接收者處理數據的機會,儘管使用最簡單的約定是最安全的。

Microsoft Excel會打開.csv文件,但依賴於系統的地區設置,它可以使用分號作為分隔符來代替逗號,這是由於在某些語言中逗號被用作小數點。並且,Excel的許多地區版本不能在CSV中處理Unicode。當遇到這種困難時,一個簡單的解決方案是將文件擴展名從.csv變為.txt;然後從一個已經運行的Excel中用「打開」命令打開文件。

當粘貼文本數據到Excel中時,通常制表符被用作分隔符:如果你複製「hello<tab>goodbye」到剪貼板中並把它粘貼到Excel中,它會進入到兩個單元格中。「hello,goodbye」粘貼進Excel會進入一個單元格中,包括逗號。如果您在Excel中使用「文本到列」功能並且改變設置,它同樣為粘貼進文本數據改變設置。

OpenOffice.org CalcLibreOffice Calc處理CSV文件,並且通過一個文本導入對話框粘貼文本,對話框要求用戶自己指定分隔符、編碼、列格式等。

在類Unix系統上,有許多工具程序至少可以處理某些CSV文件。許多此類工具有辦法改變分隔字符,但是很少能支持任何其它變體(或Unicode)。這些可用的程序有:

  • column
  • cut
  • paste
  • join
  • sort
  • uniq(-f來跳過比較前N個字段)

參見

註釋

  1. ^ 列表方式的I/O, Fortran 77语言参考资料(英文), Oracle, [2013-08-16], (原始內容存檔於2021-02-26) 
  2. ^ 例如Microsoft Word。
  3. ^ 例如LibreOffice 3.4的.csv設置導入。
  4. ^ 例如,這一錯誤頁面存檔備份,存於網際網路檔案館(英文)實際上記載了OpenOffice和LibreOffice在處理文本字段內換行符的不同。
  5. ^ CSV文件的读写(英文). [2011年7月24日]. (原始內容存檔於2012年10月22日). 沒有「CSV標準」 
  6. ^ Y. Shafranovich. 逗号分隔值(CSV)文件的通用格式和MIME类型(英文). [2011年9月12日]. (原始內容存檔於2021年5月5日). 

參考資料

外部連結