はじめに
ユーザー入力を含むCSVデータを扱う機会があり、改めてCSVの仕様について調べました🦕
💡 この記事でわかること
- CSVとは何か、その基本構造
- 改行コード(LF / CR / CRLF)について
- ダブルクォートによるエスケープの仕組み
この記事ではCSVの基礎知識についてまとめています。
読み込みやパースの実装については、次回以降の記事で紹介しようと思います💭
CSVとは
CSV(comma-separated values)とは、データをカンマで区切って表現するテキストファイル形式です。
CSVには明確な標準規格はありませんが、最も広く受け入れられている定義は RFC 4180 です。多くのCSVライブラリが RFC 4180 に準拠しています。
CSVの基本構造
改行で区切られた1行が1レコード、カンマで区切られた各値が1フィールドを表します。
商品コード,商品名,カテゴリ,価格
P001,ヘッドホン,電子機器,8000
P002,マウス,電子機器,3500
CSVのフォーマット仕様
RFC 4180 では、CSVのフォーマットについて以下の7つのルールが定義されています。
- 各レコードは改行(CRLF)で区切る
- ファイルの末尾での改行は任意
- ヘッダー行は任意
- 各行のフィールド数は同じにする
- フィールドはダブルクォートで囲んでも囲まなくてもよい。囲まない場合、フィールド内にダブルクォートを含めてはならない
- 改行・ダブルクォート・カンマを含むフィールドはダブルクォートで囲む
- フィールド内のダブルクォートは、直前にダブルクォートをつけてエスケープする
改行コード
改行コードとは、行の終わりを示す特殊文字です。
改行コードには3種類あり、OSによって使われるものが異なります。
| 改行コード | 表記 | 16進数 | 使用環境 |
|---|---|---|---|
| CR | \r |
0x0D |
Classic Mac OS |
| LF | \n |
0x0A |
Unix, Linux, macOS |
| CRLF | \r\n |
0x0D0A |
Windows |
CR(Carriage Return)
カーソルを行の先頭へ移動する動作を表します。
LF(Line Feed)
カーソルを次の行へ下に移動する動作を表します。
CRLF
CRとLFを組み合わせたもので、カーソルを行の先頭へ移動してから次の行へ下に移動するという動作を表します。
➡️ RFC 4180 ではCSVの改行コードとしてCRLFを規定していますが、CRやLFなど他のケースもあることを考慮する必要があります。
ダブルクォート
CSVには「特殊な文字を含むフィールドはダブルクォートで囲む」というルールがあります。
ダブルクォートが必要なケース
以下の文字を含むフィールドは、ダブルクォート(")で囲む必要があります。
- カンマ(
,) - 改行(CRLF)
- ダブルクォート(
")
具体例
フィールド内にカンマがある場合
NG:5つのフィールドとして認識されてしまう
ノートPC,電子機器,軽量,高性能,長時間バッテリー
OK:3つのフィールドとして認識される
"ノートPC","電子機器","軽量,高性能,長時間バッテリー"
フィールド内に改行がある場合
NG:3つのレコードとして認識されてしまう
ノートPC,電子機器,特徴:
・軽量設計
・長時間バッテリー
OK:1つのレコードとして認識される
"ノートPC","電子機器","特徴:
・軽量設計
・長時間バッテリー"
フィールド内にダブルクォートがある場合
NG:パーサーがクォートの開始位置を誤認識してしまう
"ノートPC","電子機器","通称"プロモデル""
OK:直前にダブルクォートをつけてエスケープする
"ノートPC","電子機器","通称""プロモデル"""
⚠️ 注意点
CSVを処理する際、単純なカンマ分割ではダブルクォート内のカンマも区切り文字として認識されてしまいます。
正しく処理するには、ダブルクォートの状態を考慮したパーサーが必要です。
📗 関連記事
固定フォーマットで特殊文字を含まないケースでは、シンプルな自作処理で対応した話も書いています。
まとめ
- 改行コードは環境によって異なる(LF / CR / CRLF)
- カンマ・改行・ダブルクォートを含むフィールドはダブルクォートで囲む
- フィールド内のダブルクォートは "" でエスケープする
参考
