2014年11月12日
それでも独自のCSVを書くつもりですか?
(2014-05-25)by Thomas Burette
本記事は、原著者の許諾のもとに翻訳・掲載しております。
一部誤訳の指摘があったため、修正しました!ご迷惑おかけして申し訳ございません!
あなたは自分でCSVを書いてみたいですか? フィールドはコンマで区切り、行は改行で分けます。簡単ですよね。数行書けば勝手が分かるというものです。
でも、ちょっと待ってください。
フィールド内にコンマがある場合は?
ダブルクォート(”)で、該当のフィールドを囲みましょう。簡単ですね。
では、ダブルクォートで囲めるフィールドに例外はあるのでしょうか?
フィールド内にダブルクォートがある場合は?
フィールド内の各ダブルクォートに対して、ダブルクォートを二重化して適用しましょう。そうすれば元のダブルクォートをエスケープすることができます。
なお、二重化したダブルクォートと空フィールドを囲んでいるダブルクォート( ...,"",...
)を勘違いしないように気を付けてください。
フィールド内に改行がある場合は?
その場合も、ダブルクォートで該当のフィールドを囲む必要があります。
使用可能な改行コードは?
CRLF、CR、それともLF? 複数の改行がある時は?
改行コードが変わる場合は?
例えば、フィールド内の改行は、行の最後尾の改行とは違うものです。
ここまでは大丈夫ですか?
行の最後尾に余分なコンマがある場合は?
最後尾に空フィールドがありますか? それともただの不必要なコンマでしょうか?
行ごとにフィールド数が異なる場合は?
空白行がある場合は?
それはEOFですか? それとも1つの空フィールド? またはフィールドが全くない状態でしょうか?
空白は?
フィールド内の先頭/末尾に空白がある場合は、どうしますか?
入手したCSVで、コンマの後に全てスペースが入っていて、それがデータの一部でない場合は、どうしますか?
フィールドの区切り文字がコンマでない場合は?
冗談を言っているわけではありませんよ。
小数点の記号として、コロンではなくコンマを使う国もあります。そういった国では、Excelはセミコロンを区切り文字としてCSVファイルを出力します。この問題を回避するために コンマの代わりにタブ を使うファイルもあります。他にも 非表示のASCII文字 を使うファイルさえあります。
任意のCSVファイルを読み込む時は、その点を考慮しなければなりません。ファイルの中でどの記号が区切り文字として使用されているか示すものはありませんからね。
CSVを読み込むプログラムが複数の区切り文字を使用している場合は?
Excelのように、ファイルをディスクやWebから読み込む際に、様々な区切り文字に対応するアプリケーションもあります。適切な区切り文字が設定されているか確認してください。
非ASCIIデータが含まれる場合は?
UTF-8を使えばいいだけじゃないでしょうか? でも、待ってください。
CSVを読み込むプログラムがロケールに依存したエンコードを使用している場合は?
ファイルがどのエンコードを使っているのかプログラムが自動的に判別できるわけではありません。ファイルによっては、コンピュータのロケールに依存したエンコードを使っているものもあります。
つまり、CSVを保存したコンピュータと違うコンピュータでファイルを開くと、気付かないうちにデータが破損する恐れがあるということです。
ファイルにBOMを挿入したら?
BOM(バイトオーダーマーク) が、使用されているUnicodeエンコーディングを判別してくれるものですよね。そういう役割でしょう(実際はエンディアンを判別する役割ですが、今回そこまでは触れません)。
でもBOMを挿入すると、ExcelがCSVをテキストファイルと見なし、CSVとしては扱ってくれません。つまり指定した改行は処理されないということです。
それでもCSV処理のための独自コードを書きたいですか?
CSVというのはあまりよく定義されたファイルフォーマットとは言えません。 RFC4180 は実情とはかけ離れています。全てのプログラムが少しずつ違うやり方でCSVを処理しているように思えます。更にこれ以上のバリエーションは不要です。どうぞ既存のライブラリを使ってください。
CSVのプロバイダやサプライヤ、そこから発信されるデータを完全に掌握できるというのなら、信頼できる自動化システムを構築できるでしょうけれどね。
手にしたCSVが任意のものなら、データが正しいことを保証する方法はただ一つ、ユーザが調査するということです。そして区切り文字や、クォートの規則などを最終的に特定しなくてはなりません。そうしなければエラーになってしまうか、気付かないうちにデータが破損するという事態になりかねません。
今、世の中に出回っているファイルをうまく処理できるようにCSVコードを書くのは至難の業です。泥沼にはまることになるかもしれません。RubyのCSVライブラリは2321行あるんですよ。
ご意見は Hacker News と Reddit までどうぞ。
株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表
- Twitter: @yosuke_furukawa
- Github: yosuke-furukawa