CSVの途中から列がずれたり、1件のデータが何行にも分かれたり、残り全部が1つのセルに入ったりする場合、原因はダブルクォート周辺にあるかもしれません。
CSVでは引用符の内側にカンマや改行を含められるため、「改行位置を直す」「カンマを消す」といった見た目だけの修正は危険です。
まず、正常なCSVと異常なCSVを見分けます。
正常な例:引用符内の改行
次は正常な構造として扱える例です。
id,note
1,"1行目
2行目"
2,完了
1行目 と 2行目 の間に改行がありますが、フィールド全体がダブルクォートで囲まれているため、1件の値として扱えます。
この改行を「行の終わり」と決めつけて分割すると、正常なデータを壊します。
異常な例:閉じていない引用符
次は問題があります。
id,note
1,"開始しました
2,完了
3,保留
"開始しました で開いた引用符が閉じていません。
CSVパーサーによっては、その後の改行やカンマまで同じフィールドの一部として読み続けます。その結果、
- 途中から列数が合わない
- 残りの行が1レコード扱いになる
- ファイル末尾で引用符エラーになる
といった症状が出ます。
異常な例:フィールド内の引用符を1個だけ書く
RFC 4180で文書化された一般形式では、引用符で囲んだフィールドの中にダブルクォートを入れる場合、2個に重ねます。
正常例:
1,"he said ""OK"""
不正になりやすい例:
1,"he said "OK""
取り込み側の実装によってエラーの出方は違いますが、引用符の開閉状態が崩れる原因になります。
「行数が増えた」だけでは異常と決めない
CSVのセル内改行があると、物理的な行数とレコード件数は一致しません。
そのため、
ファイルは1001行あるのに、Excelでは1000件しかない
といった状況だけでは異常とは言えません。ヘッダーを含めるか、引用符内改行があるかで見え方が変わります。
確認するべきなのは、引用符の状態を考慮した論理レコード数です。
列数ズレとの見分け方
引用符エラーと列数ズレは似た症状になります。
たとえば、
id,name,amount
1,田中,1000
2,佐藤,2000,EXTRA
は単純な列数ズレです。
一方、
id,name,note
1,田中,"正常"
2,佐藤,"未完了
3,鈴木,完了
では、2行目の引用符が閉じていないため、その後の構造まで巻き込まれます。
特定の1レコードだけ列数が違うのか、その行以降が連鎖的に崩れるのかを見ると切り分けやすくなります。
直し方:まず異常箇所を特定する
修正は次の順で行います。
- 元ファイルをコピーする
- エラーが始まる最初の論理レコードを探す
- その前後の引用符を確認する
- 作成元データと照合する
- 正しい閉じ位置が分かる場合だけ修正する
- 修正後にもう一度パースする
重要なのは、閉じていない引用符の位置を機械的に推測しないことです。
途中に引用符を1個足せば読み込めるようになっても、元データとは違う区切り方になっているかもしれません。
やってはいけない修正
エラーを消すためだけに、次の処理を自動化するのは避けたほうが安全です。
- 改行ごとにレコードを分割する
- 値の中のカンマを削除する
- 閉じていない引用符を行末で自動的に閉じる
- 列数を合わせるために余ったフィールドを捨てる
- 欠けた列を推測して補う
CSV修復の目的は「パーサーを黙らせること」ではなく、元のフィールド値とレコード境界を復元することです。
修正後の確認
修正したファイルは、最低限次を再確認します。
- 論理レコード数
- 各レコードの列数
- 引用符内の改行
- 引用符内のカンマ
""で表現されたダブルクォート- 先頭ゼロや長いID
再読み込みしてエラーが消えただけでなく、値が変わっていないことまで確認します。
まとめ
CSVで改行や引用符のエラーが出たときは、まず「正常なセル内改行」なのか「閉じていない引用符」なのかを分けます。
改行単位で切る、カンマを消す、引用符を推測で足すといった修正は、読み込めてもデータの意味を壊す可能性があります。
正常な引用符構造を理解し、最初に壊れた論理レコードを特定してから修正するのが安全です。
参考一次資料
- RFC Editor: RFC 4180
https://www.rfc-editor.org/info/rfc4180/
