CSVをExcelで開いたら日本語が読めない、APIのレスポンスが「???」になる、フォームに貼り付けた文字列が検索に引っかからない——文字化けや文字の不一致は、原因が見えにくく時間を取られがちなトラブルです。しかも「見た目は同じなのに一致しない」というケースでは、そもそも何が起きているのか気づくまでが大変です。この記事では、文字化けの原因を特定して直す手順を、文字コードの基礎からバイト列の確認、Unicodeの特定、見えない文字の検出まで順番に整理します。
1. 文字コードの違いを理解する
まず、なぜ文字化けが起きるのかを押さえます。コンピュータは文字を数値(バイト列)として保存しており、その対応表が文字コードです。書いたときと読むときで違う対応表を使うと、別の文字として解釈されて化けます。日本語で問題になるのは主に UTF-8 と Shift_JIS の混在です。現在のWebやAPIはほぼ UTF-8 ですが、Excelが書き出すCSVや古いシステムは Shift_JIS のことがあります。重要なのは「データが壊れている」のではなく「解釈が違うだけ」という点で、元のファイルを正しい文字コードで読み直せば元通りになります。化け方の形からも当たりが付きます。「縺薙s縺ォ縺。縺ッ」のように「縺」「繧」が並ぶのは UTF-8 を Shift_JIS として読んだ形、「ã“ã‚“ã«ã¡ã¯」のように「ã」が並ぶのは UTF-8 を欧文の文字コードとして読んだ形、「�」や「◆」ばかりになるのは Shift_JIS を UTF-8 として読んだ形です。日本語が全部「?」になるのは読み違えではなく、日本語を持たない文字コードへの変換で文字が捨てられた跡で、こちらは元のデータからやり直すしかありません。
2. 元のファイルを正しい文字コードで読み直す
原因が読み違えなら、直し方は「正しい文字コードで読み直す」です。ただ、ファイルの中にはどの文字コードで書いたかが記録されていない(BOM がある場合を除く)ので、実際に読んでみて確かめます。Text Encoding Checker にファイルをドロップすると、UTF-8・Shift_JIS・EUC-JP のそれぞれで読んだ結果が並び、読めないバイトの数と日本語らしさから、いちばん可能性の高いものを示します。UTF-8 は決まりが厳しく、Shift_JIS のファイルを UTF-8 として読むとほぼ必ず読めないバイトが出るので、読めないバイトが0なら UTF-8 でほぼ確定です。正しいものを選んだら、そのまま UTF-8 で保存し直せます。Excel でダブルクリックして開く CSV なら BOM 付き、プログラムや JSON で使うなら BOM なしを選びます。なお、化けた文字列しか手元に無い場合は「化けた文字列を戻す」に貼り付けると、3通りの読み違えを逆にたどって戻します。ただし UTF-8 を Shift_JIS として読んで化けた文字列は、読めなかったバイトが捨てられているため、一部の文字は戻りません(〓 で示します)。化けた状態で上書き保存すると元のバイトが失われるので、まず元のファイルを探すのが先です。
この手順で使うツール
Text Encoding Checker
文字コードを判定して UTF-8 に変換 — 化けた文字列の復元も
3. 文字数とバイト数のずれを確かめる
「入るはずなのに入らない」「途中で切れる」という問題は、文字化けではなく数え方の違いが原因のことが多くあります。String Inspector に文字列を貼り付けると、見た目の文字数・コードポイント数・UTF-16 の長さ・UTF-8 のバイト数を並べて表示します。UTF-8 では英数字が1バイト、ひらがなや漢字が3バイト、絵文字が4バイトです。古い MySQL の utf8(utf8mb3)は1文字3バイトまでしか入らないため、絵文字を保存するとエラーになったり、その位置で切れたりします。utf8mb4 にするのが対策です。さらに、絵文字は見た目1文字でも複数の部品でできていることがあります。家族の絵文字「👨👩👧」は見た目は1文字ですが、コードポイントは5(人物3つと、つなぐ ZWJ が2つ)、JavaScript の length では8、UTF-8 では18バイトです。上限を何で数えているかを相手の仕様で確かめ、同じ数え方で比べてください。
この手順で使うツール
String Inspector
文字列を1文字ずつ分解 — Unicodeコードポイント・UTF-8バイト数・文字種を可視化
4. 見た目が同じなのに一致しない文字を突き止める
「この文字だけ検索に引っかからない」場合は、見た目が同じ別の文字を疑います。多いのは、全角と半角(A と A)、半角カナ(ガ)、丸数字(①)、そして濁点の付け方(「が」1文字か、「か」+結合用の濁点の2文字か。macOS のファイル名は後者になりやすい)です。String Inspector はこれらを見つけると、正規化(NFC・NFKC)した結果を並べて表示します。NFC は結合した濁点を1文字にまとめ、NFKC はさらに全角英数を半角に、半角カナを全角に、① を 1 にそろえます。ただし正規化でもそろわない文字があります。マイナス「−」(U+2212)、長音「ー」(U+30FC)、ダッシュ「–」(U+2013)は別の文字のまま残ります。波ダッシュも要注意で、Windows で作った Shift_JIS のファイルの「〜」は、Windows の方式(CP932)で読み込むと U+FF5E(全角チルダ)になり、macOS などで入力した「〜」(U+301C)とは一致しません。こうした文字は String Inspector の文字グリッドでコードポイントを確かめ、Unicode Browser にその文字を貼り付けて正式名を見て、どちらにそろえるかを決めて置き換えます。
この手順で使うツール
Unicode Browser
Unicode文字を名前・コードポイントで検索・ブロック別ブラウジング
5. 見えない文字を見つける
最も厄介なのが、画面に表示されない文字です。代表は、ゼロ幅スペース(U+200B)、ノーブレークスペース(U+00A0。見た目は空白だが普通の空白と一致しない)、全角スペース、文字列の先頭に紛れた BOM(U+FEFF)です。Web ページや PDF からコピーした文字列に混ざりやすく、目で見ても正しいのに一致しない原因になります。String Inspector は、こうした文字が含まれていると名前と個数を一覧にし、文字グリッドでは赤い枠で示します。ひとつ注意したいのが改行コードで、ブラウザの入力欄は貼り付けた CRLF を必ず LF に変えてしまうため、貼り付けでは CRLF と LF の違いを調べられません。改行コードやファイル先頭の BOM はファイルのまま読む必要があり、Line Ending Inspector にファイルをドロップすると、CRLF・LF の混在と BOM の有無を確かめられます。
この手順で使うツール
String Inspector
文字列を1文字ずつ分解 — Unicodeコードポイント・UTF-8バイト数・文字種を可視化
6. 入り口から出口まで UTF-8 でそろえる
最後に、文字化けを起こしにくくする対策です。基本は「入り口から出口まで UTF-8 でそろえる」ことです。HTML は meta charset、HTTP レスポンスは Content-Type の charset、データベースは接続とテーブルの文字セット(MySQL なら utf8mb4)、ファイルは保存時の文字コード——どこか1か所でも違うと化けます。外から受け取るファイルが Shift_JIS の可能性があるなら、取り込む直前に一度だけ UTF-8 に変換し、以降は UTF-8 だけを扱う形にすると、変換の場所が1か所に決まって追いやすくなります。Excel に渡す CSV だけは、BOM 付きの UTF-8 にしておくと文字化けせずに開けます。
この手順で使うツール
Text Encoding Checker
文字コードを判定して UTF-8 に変換 — 化けた文字列の復元も
まとめ
文字化けの解決は「化け方の形から原因に当たりを付ける → 元のファイルを正しい文字コードで読み直す → 文字数とバイト数のずれを確かめる → 見た目が同じ別の文字を突き止める → 見えない文字を見つける → UTF-8 でそろえる」の流れで進めると、原因にたどり着けます。特に「化けた状態で上書き保存すると戻せない文字が出る」「正規化でもそろわない文字(− ー – 〜)がある」「改行コードは貼り付けでは調べられない」の3つは、知らないと遠回りになるポイントです。