逗號分隔值

逗號分隔值（comma-separated values，縮寫：CSV，有時也稱為字符分隔值，因為分隔字符也可以不是逗號），其文件以純文本形式存儲表格數據（數字和文本）。純文本意味著該文件是一個字符序列，不含必須像二進位數字那樣被解讀的數據。CSV文件由任意數目的記錄組成，記錄間以某種換行符分隔；每條記錄由欄位組成，欄位間的分隔符是其它字符或字串，最常見的是逗號或制表符。通常，所有記錄都有完全相同的欄位序列。

CSV文件的格式不存在通用標準，也沒有指定所使用的字符編碼，但是在RFC 4180中有基礎性的描述。

而7-bit ASCII是最基本的通用編碼。

## 用法

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

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

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

- 純文本，使用某個字符集，比如ASCII、Unicode、EBCDIC或GB2312（簡體中文環境）等。
- 由記錄組成（典型的是每行一條記錄）。
- 每條記錄被分隔符分隔為欄位（典型分隔符有逗號、分號或制表符；有時分隔符可以包括可選的空格）。
- 每條記錄都有同樣的欄位序列。

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

## 歷史

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

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

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

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

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

## 常規功能

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

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

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

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

欄位會變化的統計資料庫往往有著類似關係的結構，但是會有一些欄位組是可重複的。例如，健康資料庫如人口與健康調查，對於一名給定的父母會為每個孩子重複一些問題（也許直到某個確定的最大的孩子數目）。統計分析系統往往包含可以「旋轉」這類數據的工具：例如，一條包含5個孩子資訊的「父母」記錄，可以被分解為5條單獨的記錄，每條記錄包含（a）一個孩子的資訊，和（b）一份所有未指定孩子的資訊的拷貝。CSV可以用「橫的」或「豎的」形式來表達這類數據。

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

## 缺乏規範

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

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

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

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

## 進行中的標準化

「CSV」格式中大量變體的存在說明並沒有一個「CSV標準」。在常見用法中，幾乎任何定界符分隔值都可以被統稱為「CSV」文件。不同的CSV格式可能不會兼容。

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

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

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

## 技術背景

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

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

在電腦科學術語中，CSV文件可以被認為是一個「平面文件資料庫」。

## 基本規則及舉例

存在許多描述「CSV」格式的非正式文件。IETF RFC 4180（如上所述）定義了格式「text/csv」網際網路媒體類型，並已註冊於IANA。Shafranovich另一個相關規範由含欄位文本提供。提供了一個概述，說明了在最廣泛使用的應用程式中所使用的變體，並解釋了CSV怎樣才能最好地被使用和支持。

這些和其它「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/定界符分隔值文件（小數點是逗號，值分隔符是分號）舉例：

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

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

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

- column
- cut
- paste
- join
- sort
- uniq（-f來跳過比較前N個欄位）

## 外部連結

- B2B（商業對商業）應用的CSV-1203文件格式規範
- 如何：逗號分隔值（CSV）文件格式
- RFC 4180：CSV文件格式的RFC規範

## 基本資料

- 日語原文：逗號分隔值、逗號分隔列
- 擴展名：.csv或.txt
- mime：text/csv
- 類型：跨平台，串行數據流
- 作為容器：資料庫按欄位分隔的列表的資訊組織
- 標準：RFC 4180