0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CSVファイルの解析を row.split(',') で済まさない

Posted at

JavaScriptでCSVファイルを読み込むコードを書きたいのでjs csv 読み込みでググったら、検索結果上位のほぼ全てのサイトが自力でrow.split(',')したりする感じの書き方をしていたので書く記事。

CSVファイルには標準規格がある

CSVとはComma-Separated Valuesの略で、その名の通りコンマで区切られた複数のフィールドで構成された1レコードを1行としてそれが複数行連なったテキストファイルのことである、というのは皆さんご存知でしょうがCSVファイルはそれが全てではありません。

CSVファイルとは慣習的になんとなく使われているファイルフォーマットではなく、標準規格があるフォーマットです。その規格を満たしていなければCSVファイルではない、とまでは言いませんが標準があるならそれに従うべきです。

「いや、そんなこと言ったって標準規格は超難解で使いもしない機能盛りだくさんだからだからみんな簡易的な実装してんじゃないの?」と思うかもしれませんが、そんなことはありません。

その規格はRFC4180で定められています。規格といっても全部でたった8ページしかなく、ファイルフォーマットを定めているのはそのうち2ページくらいです。英語でも5分あれば読めるレベルです。

フィールドをダブルクオートでくくれる

単にコンマでフィールドを区切って改行でレコードを区切っただけだと、フィールドにコンマと改行を入れられません。よって標準規格ではダブルクオートでフィールドを囲むことでそれらの文字を入れられるようにしています。ダブルクオートで囲まれたフィールドの中でダブルクオートを使う場合はダブルクオートを2回書くことでエスケープします。

普通のフィールド,"カンマ:,","ダブルクオート:""","改行:
"

コンマや改行を一切含まないフィールドをダブルクオートで囲っても問題ありません。私はCSVを書き出すときは常にダブルクオートで囲ってます。それらの文字が入ってるかどうかで処理を分けるのが面倒ですからね。

閑話 - その他標準規格の細部

  • 最終レコードの後の改行はあってもなくてもよい
  • コンマの前後にホワイトスペースを入れてはいけない
    • そのままホワイトスペースを含んだフィールドとして扱われる
  • 各レコードの最後にコンマを置いてはいけない
    • レコードの最後に空文字のフィールドがあるものとして扱われる
  • 各レコードのフィールド数は同じであるべき
  • (改行コードはCR LF)
    • あくまで規格上は。実際にはUnix系の改行コードLFでもいい。

解析するときはライブラリを使おう

このようにCSVファイルにはダブルクオートで囲むことができる仕様があります。そしてこの仕様はExcelなど多くのソフトで対応している仕様です。単純にrow.split(',')すればいいだけではないです。

この仕様は単純で自分でも書けるでしょうが、ライブラリを使うのが無難でしょう。CSVを解析するときはライブラリを使いましょう。

(ガチ閑話)

js csv 読み込みで出てきた某テック○カデミーの記事、タイトル「CSVファイルを読み込む方法」で改行で区切るとかコンマで区切るとか一切せずにファイルの内容文字列としてそのままコンソールに出して終わっててワロタ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?