この記事では、 Unicode において表示不可能な文字を表現する「置換文字」について説明する。
この記事に出てくるコードの動作確認は以下の環境で行った。
- Deno 1.26.0
- TypeScript 4.8.3
概要
Unicode において、表示しようとした文字が何らかの理由で表示不可能なとき、黒い菱形に白いクエスチョンマークが書かれた文字が表示される。
「�」がそうなのだが、環境によっては表示されずカギカッコの中が空白になっているかもしれないので、画像も載せておく。
この文字を「置換文字」と呼ぶ。
サロゲートペアとして不正なケース
文字が表示不可能な例として、サロゲートペアとして正しくないケースがある。
サロゲートペアや Code Point の概要は以前書いたので、必要ならこちらを読んで欲しい。
numb86-tech.hatenablog.com
Code Point のうち一部分はサロゲートペアに使うものとして予め定められており、単独で文字を表現することはない。
具体的にはU+D800
からのU+DFFF
の 2048 文字分がそれに該当する。
これらの Code Point は代用符号位置と呼ばれる。
さらに、代用符号位置は前半(U+D800
〜U+DBFF
)と後半(U+DC00
〜U+DFFF
)に分かれており、前半を上位サロゲート、後半を下位サロゲートとして使うことも決まっている。
上記のルールに反した場合、無効なデータと見做され置換文字が表示される。
// 単独の代用符号位置で文字を表現することはできない console.log(`\u{d800}`); // � // dc00 が上位サロゲートに来ることはないし、 d800 が下位サロゲートに来ることもない console.log(`\udc00\ud800`); // ��
置換文字の Code Point や Code Unit について
表示不可能な文字は全て�
として表示しようというだけの話なので、表示結果が同じ�
だったとしても、 Code Point や Code Unit が異なれば、それは別の文字である。
const x = `\udc00`; const y = `\udc01`; const z = `\udc02`; // 三文字とも � と表示されるが…… console.log(x, y, z); // � � � // 全て別々の文字である console.log(x === y); // false console.log(x === z); // false console.log(y === z); // false
ちなみに、�
そのものの Code Point はU+FFFD
である。
console.log("�".codePointAt(0)?.toString(16)); // fffd