BlueprintLab Deep Guide
UTF-8・Shift_JIS・BOM完全ガイド――CSVの文字化けを「文字コード」で切り分ける
文字化けは「CSVが壊れた」とは限りません。保存した文字コードと、開く側が想定した文字コードがずれているだけ、ということがかなりあります。
CSVを開いたら、日本語が 譁 や 縺 だらけになった。
ファイル名は普通の .csv。
もう一度ダウンロードしても同じ。
こうなると「ファイルが壊れている」と思いたくなるんですが、まずは待ってください。
中身はそのままで、開く側が違う読み方をしているだけということがかなりあります。
文字化けは、CSVの構造より「文字をどうバイト列から戻したか」の問題です。
逆に、日本語は普通に読めるのに全部A列なら、それは文字コードではなく区切り文字の問題かもしれません。
まずこの2つを分けるだけで、かなり話が簡単になります。
同じファイルでも、読むルールが違うと別の文字に見えます
コンピューターの中では、「山田」という文字も最終的にはバイト列として保存されています。
保存するときには、UTF-8やShift_JIS系などのルールに従って文字をバイトへ変換します。
そして開くときは、その逆です。
ここで作成側と読み込み側のルールがずれると、同じバイト列から違う文字を組み立ててしまいます。
なので、文字化けして見えていても、元ファイルのバイト列が壊れたとは限りません。
読解ルールが食い違っているだけということがあるんです。
これは、文字化けしたCSVをいきなり修正・上書きしない方がいい理由でもあります。
まず読み方を変えてみます。
UTF-8は「文字の種類」ではなく、Unicodeをバイトへ変える方法です
UTF-8という名前はよく見ますが、ここを全部覚える必要はありません。
ざっくり言うと、Unicodeという大きな文字体系にある文字を、ファイルや通信で使えるバイト列へ変換する方法の一つがUTF-8です。
今のWeb、API、JSONなどではUTF-8が中心です。
ただし、.csv という拡張子には「UTF-8で保存する」という意味はありません。
同じCSVでもUTF-8、Shift_JIS系、その他の文字コードで保存できます。
つまり、
CSVは“表をどう区切るか”の話。UTF-8は“文字をどう保存するか”の話。
別のレイヤーなんです。
文字コードを直しても全部A列が直らないことがあるのは、このためです。
「Shift_JIS」と書いてあるのに合わない。ここは少し名前がややこしいです
日本の業務システムでは、今も「Shift_JISで出力」「SJISで取込」といった指定を見かけます。
ただ、実務ではこの名前の周辺に少し幅があります。
Windowsで長く使われてきた日本語コードページ932や、Windows-31J / MS932と呼ばれるものが関係してきます。
利用者側から見ると、「Shift_JISと書いてあるから全部同じ」と思いたくなるんですが、厳密には実装やラベルの扱いに差があります。
ここで大事なのは、用語を暗記することではありません。
相手システムが実際に何を受け入れるかを見ることです。
仕様書に Windows-31J、CP932、Shift_JIS など具体的な指定があるなら、その表記を優先します。
UTF-8からShift_JIS系へ変換すると、「読める」以外の問題も出ます
UTF-8は非常に広い文字を扱えます。
一方、Shift_JIS系のようなレガシー文字コードでは、Unicodeにある全ての文字をそのまま表現できるわけではありません。
例えば絵文字や一部の記号・文字を含むデータを変換すると、
- エラーになる
?などへ置換される- ツールによっては代替文字へ変わる
といったことがあります。
ここが少し怖いところです。
文字化けが消えた=変換が完全に成功した、とは限りません。
日本語が一見読める状態になっても、変換先に存在しない文字が落ちていないかは別に見ます。
氏名、住所、商品名、自由記述などは、変換後に数件抜き取って確認すると安心です。
BOMは「UTF-8の別バージョン」ではありません
UTF-8ファイルの先頭に EF BB BF という3バイトが付くことがあります。
これがBOMです。
名前は Byte Order Mark。
ところがUTF-8では、UTF-16やUTF-32のようにバイト順を切り替える問題がありません。
Unicode Consortiumも、UTF-8でBOMを使う場合は、バイト順指定ではなくUTF-8であることを示す署名として使われると説明しています。
名前だけ見ると「バイト順のための印」に見えるので、ここはちょっと意外なんですよね。
UTF-8自体は、BOMなしでも成立します。
なので、
- UTF-8
- UTF-8 BOM付き
は「文字の表現方式が全く別」というより、先頭に識別用の印があるかどうかの違いです。
BOMは、付ければ付けるほど安全になるわけではありません
「じゃあBOM付きにしておけば親切なのでは?」と思うんですが、そうとも限りません。
BOMを期待しないシステムでは、先頭の余計なバイトとして扱われることがあります。
Unicode Consortiumも、先頭に特定のASCII文字を期待するような形式ではBOMが干渉する場合があると説明しています。
なので結論はシンプルです。
取込先がBOM付きを要求するなら付ける。要求していないなら、その仕様に合わせる。
BOMは万能な互換性スイッチではありません。
.csv を見ても文字コードは分かりません。それで普通です
ファイル名が products.csv でも、UTF-8かShift_JIS系かは分かりません。
ここで「知らない自分がおかしいのでは」と思う必要はありません。
情報がファイル名に書かれていないんです。
見る順番はこうです。
- 出力元・取込先の仕様を見る。
- 指定がなければUTF-8としてプレビューする。
- 日本語が崩れるならShift_JIS系でも見る。
- 文字だけでなく、列の分かれ方も見る。
- 変換した場合は、置換された文字がないか確認する。
自動判定ツールも便利ですが、判定はあくまで候補です。
ASCIIだけの短いCSVなら、UTF-8でもShift_JIS系でも同じように読めることがあります。
最後はプレビューと相手仕様で確認します。
Excelなら、ダブルクリックより[テキストまたはCSVから]で見た方が分かりやすいです
大事なCSVなら、Excelを先に開きます。
そして [データ]→[テキストまたはCSVから] でファイルを選びます。
ここで読み込み前のプレビューが出ます。
文字コードを切り替えて、日本語が自然に戻るかを見ます。
ここで文字は直った。でも全部A列のまま。
その場合は、次に区切り文字です。
逆に、列はきれいに分かれているのに日本語だけ崩れているなら、文字コードへ戻ります。
文字と構造を別々に見る。
これだけで、CSVの文字化けはかなり切り分けやすくなります。
文字コード変換で見るべきなのは、「変換ボタンが成功したか」ではありません
UTF-8からShift_JIS系へ変換して、ツールが「完了」と出た。
それだけではまだ終わりません。
見るのは、変換後のデータです。
- 行数が変わっていないか
- 列数が変わっていないか
?や�が増えていないか- 氏名・住所・商品名などの日本語が残っているか
- 取込先へ少量で入るか
特に、もともとUTF-8でしか表せない文字が含まれていた場合は注意です。
保存形式を変えるだけの作業に見えて、実際には“表現できる文字の範囲”も変わることがある。
ここが文字コード変換で覚えておくと役立つところです。
結局、UTF-8・UTF-8 BOM付き・Shift_JISのどれを選べばいい?
迷ったときの優先順位はこれです。
1. 取込先の仕様
UTF-8 BOM付き と書いてあるなら、それに合わせます。
2. 出力元の仕様
元システムがShift_JIS系を前提にしているなら、まずその条件を確認します。
3. 仕様が分からないならプレビューとテスト
日本語が自然に読めるか、変換後に欠落がないか、少量で取り込めるかを確認します。
「UTF-8の方が新しいから」「BOM付きの方が親切そうだから」で決めるより、読む相手に合わせる方が安全です。