CSV のカンマや改行はどう区別する? RFC 4180 を読む
CSV ファイルで住所や自由記述のようにカンマや改行を含む値を扱うと、列がずれて壊れることがあります。事実上の標準 RFC 4180 がこの問題をどう解決しているかを、具体例とともに整理します。
「カンマ区切り」なのにカンマを含む値がある
CSV (Comma-Separated Values) は、値をカンマで区切っただけの単純なテキスト形式です。ところが実際のデータでは、住所の「東京都, 千代田区」のようにカンマそのものを含む値や、自由記述欄のように改行を含む値が普通に存在します。カンマで区切るだけの素朴な実装では、こうした値を書き出すと列の数がずれ、読み込むプログラム側で正しく解釈できなくなります。
事実上の標準 RFC 4180 が定めるルール
CSV には ISO や JIS のような強制力を持つ公的規格はありませんが、IETF が 2005 年に公開した情報提供用の文書 RFC 4180 が、多くの表計算ソフトやプログラミング言語のライブラリが実際に従う「事実上の標準」として機能しています。RFC 4180 が定める主なルールは次のとおりです。
| 要素 | ルール |
|---|---|
| フィールドの区切り | カンマ (,) |
| レコード (行) の区切り | CRLF (\r\n) |
| カンマ・改行・ダブルクォートを含む値 | フィールド全体をダブルクォート (") で囲む |
| 値の中にあるダブルクォート自体 | ダブルクォートを 2 つ連続させてエスケープする ("") |
| ヘッダー行 | 任意 (RFC 4180 自体は必須にしていないが、1 行目を列名にする慣習が広く使われている) |
たとえば「佐藤, 太郎」という値をそのまま書くと name,佐藤, 太郎,age のように列がずれてしまいますが、RFC 4180 の規則に従えば次のように書きます。
name,age
"佐藤, 太郎",34
"改行を
含む値",0
1 行目はヘッダーで、2 行目の "佐藤, 太郎" はダブルクォートで囲まれているため、内部のカンマは区切りとして解釈されず 1 つの値として読み取られます。3 行目のようにフィールド内に改行があっても、ダブルクォートで囲まれている間は 1 つのレコードとして扱われ、次の " が閉じるまでレコードは終わりません。
ダブルクォート自体を値に含めたい場合
値そのものに " を含めたいときは、2 つ連続させてエスケープします。たとえば 彼は"OK"と言った という値は、次のように書きます。
comment
"彼は""OK""と言った"
読み込み側は、クォートで囲まれた区間の中で "" が出てきたら「区間の終わり」ではなく「" という 1 文字」と解釈し、その後に続く文字も同じフィールドの一部として読み進めます。
実務で注意したい点
- 表計算ソフトで保存した CSV を別のシステムに読み込ませる場合、改行やカンマを含む列があると、保存ソフトの実装によって引用のされ方が微妙に異なることがあります。読み込みに失敗したら、まずは該当の値をダブルクォートで囲んでいるかを確認すると原因を特定しやすくなります。
- 文字コードは RFC 4180 の範囲外です。日本語を含む CSV を異なるシステム間でやり取りする場合は、UTF-8 か Shift_JIS かを別途確認する必要があります。
- 行の区切りは CRLF が標準ですが、Unix 系のツールが LF (
\n) だけで出力することも多く、多くのパーサーは LF のみでも読み込めるように実装されています。
まとめ
- CSV には公的な強制規格はないが、RFC 4180 が事実上の標準として広く使われている。
- カンマ・改行・ダブルクォートを含む値は、フィールド全体をダブルクォートで囲み、内部のダブルクォートは 2 つ連続させてエスケープする。
- 実際に手元の CSV と JSON を相互変換して、この引用処理が崩れていないかを確認したい場合は、CSV ⇔ JSON 相互変換ツールでその場で試せます。
RFC 4180 の原文 (英語) は IETF の RFC Editor サイトで公開されています。https://www.rfc-editor.org/rfc/rfc4180