ASCII と Unicode
ASCII は 1960 年代の文字セットで、128 文字を定義しました:英字、数字、基本句読点、33 個の制御コード。Unicode は現代の文字セットで、現存するあらゆる言語のあらゆる文字を符号化することを目標としており、現在約 154,000 文字、増え続けています。
ほぼすべての現代システムが内部で Unicode を使っています。ASCII は歴史的ベースラインで、Unicode コードポイントの前 128 個にちょうど収まります。ASCII ファイルはすべて有効な UTF-8 ファイルです。
ASCII の使い方
ASCII は表示可能文字にバイト値 0-127 を割り当てました。値 128-255 は後に「拡張 ASCII」符号化(Latin-1、Windows-1252、Shift-JIS など)で使われ、それぞれアクセント記号、通貨記号、CJK 文字を追加しました。これにより古典的な「文字化け」問題が発生しました。あるシステムが書き、別のシステムが読み込むと、é の代わりに é が表示されます。
Web と現代のファイル形式(JSON、XML、YAML、Markdown、現代の TXT)はデフォルトとして UTF-8 に合意し、この問題をほぼ解消しました。古い符号化はレガシーデータにまだ現れます。古い Excel のエクスポート .csv は今でも Windows-1252 が使われていることがあります。
UTF-8 vs UTF-16 vs UTF-32
Unicode には複数のシリアライズ形式があります:
- UTF-8 — 可変幅(コードポイントあたり 1〜4 バイト)、ASCII 互換(先頭 128 は ASCII とバイト完全一致)。Web、すべての主要 OS、多くのファイル形式のデフォルト。
- UTF-16 — 可変幅(2 または 4 バイト)。Windows、Java、JavaScript 文字列が内部的に使用(歴史的には。現代の JS エンジンは内部で UTF-8 を使うこともあります)。
- UTF-32 — 固定幅(コードポイントあたり常に 4 バイト)。単純ですが ASCII 多用データでは無駄が多い。コードポイントへの高速ランダムアクセスが必要な一部システムが内部で利用。
システムが「Unicode」とだけ言うとき、現代の文脈ではほぼ UTF-8 を意味します。
正規表現への影響
コードの正規表現エンジンはロケールまたはエンコーディングフラグに従いバイト列を解釈します。. は ASCII モードでは「改行以外の任意文字」、Unicode モードでは「任意のコードポイント」にマッチします。\w(単語文字)は Unicode モードでは A-Z と a-z の他にも、はるかに多くの文字を含みます — é、ñ、Ω、あらゆる CJK 表意文字、など。
現代の正規表現エンジンは Unicode モードがデフォルトです。ASCII 専用動作が必要なら、明示的なフラグが必要です(例:\w の代わりに [A-Za-z])。
実用例:絵文字
“😀”(U+1F600、「にやりと笑う顔」)は 1 つの Unicode コードポイントで、UTF-8 では 4 バイト(F0 9F 98 80)。Unicode 定義上は 1 文字、UTF-8 では 4 バイト。
これが JS の “length” が U+1F600 を 2 と数える理由です(UTF-16 のサロゲートペアを考慮)。JS の string.length は UTF-16 コードユニットを操作しており、コードポイントではありません。
ツール
貼り付けた文字列のバイトとコードポイントを検査するには — 不可視文字や Unicode エスケープを含めて — Unicode Inspector をお試しください。ブラウザ内実行で、何も送信しません。
ASCII と Unicode が混在するテキスト(大多数の実文書)では、Case Converter が文字体系を跨ぐ大小規則を扱います。
関連
- 正規表現早見表 — Unicode 対応の正規表現が実際の論点のとき
- PDF to Text — エンコーディングが混在する PDF からテキストを抽出
- JSON to CSV — 文字エンコーディングが CSV を正しく開けるかを決めるケース