文字列処理の規格を読み書きするときに混乱し・曖昧になりがちなUnicode用語を正しく使い分ける
はじめに
迷ったら https://www.unicode.org/glossary/ を見るのが一番
日英対応は
- https://www.unicode.org/terminology/term_en_ja.html
- https://www.unicode.org/terminology/term_ja_en.html
Unicode符号位置 / Unicode符号点 / Unicodeコードポイント(Unicode Code Point)
0~10FFFF₍₁₆₎を表す整数値です。
この範囲をUnicode符号空間(Unicode Codespace)と言ったりします。
- Pythonの
str
の1文字
通常は、U+のあとに最低4桁の16進数をつけて表されます。(A5₍₁₆₎→U+00A5:¥)
代用符号位置 / サロゲートコードポイント(Surrogate Code Point)
符号位置の中で、D800₍₁₆₎~DFFF₍₁₆₎を指します。単独では文字を表しません。また、UTF-16以外では使いません。
Unicodeスカラー値(Unicode Scalar Value)
代用符号位置以外の符号位置です。文字コード(符号化方法)に依存しない範囲での文字の最小単位です。
スカラ値にあらずんば文字にあらず。
すなわち0~D7FF₍₁₆₎・E000₍₁₆₎~10FFFF₍₁₆₎の範囲の整数値です。
- C#・GoのRune
- Rustの
char
符号単位 / コードユニット(Code Unit)
UTF-8 / UTF-16 / UTF-32などで表した数値配列上の1つの数値です。UTF-8 / 16で顕著ですが、スカラ値を表さない場合もあります。
- UTF-8符号単位:
- C/C++の
char
(Windows以外)・char8_t
- Rustの
str
- C/C++の
- UTF-16符号単位:
- C/C++の
wchar_t
(Windows)・char16_t
- Java(・その他JVM言語)・C#(・その他.NET系言語)の
char
- Java(・その他JVM言語)・C#(・その他.NET系言語)・JavaScript(その他AltJS言語)の文字列の1文字
- C/C++の
- UTF-32符号単位
- C/C++の
wchar_t
(Windows以外)・char32_t
- C/C++の
代用符号単位 / サロゲートコードユニット(Surrogate Code Unit)
UTF-16で(不正な文字という文脈で)サロゲートと言いたくなった場合、基本的にはこれです。
UTF-16上で代用符号位置の範囲を表す符号単位です。
下の上位・下位代用符号単位に分類されます。また、正しく2つ組み合わせると、代用対になり、Unicodeスカラ値を表します。
上位代用符号単位 / 上位サロゲートコードユニット(High-Surrogate Code Unit)
D800₍₁₆₎~DBFF₍₁₆₎の範囲の代用符号単位です。下の代用対の前半部分です。
下位代用符号単位 / 下位サロゲートコードユニット(Low-Surrogate Code Unit)
DC00₍₁₆₎~DFFF₍₁₆₎の範囲の代用符号単位です。下の代用対の後半部分です。
代用対 / サロゲートペア(Surrogate Pair)
UTF-16で、上位代用符号単位→下位代用符号単位の順番で正しく組み合わせてUnicodeスカラ値を表したものです。
孤立代用符号単位(isolated surrogate code unit)
正式な用語ではないようですが、英語で代用対になれなかった片割れを英語でこう呼ぶみたいです。
日本語訳は確立していませんが、ロングマン英和や英辞郎を見る限り「孤立した」がisolatedの適切な訳だと思います。
符号化文字(Encoded Character)
- 符号位置→数値
- 符号化文字→文字
「符号位置1個分を表す普通の文字」「UTF-32・(u)int32型の値1個分の普通の文字」と言いたい場合はおそらくこの言葉が適していると思います。
公式には「抽象文字(下記)と符号位置との間の関連付け・マッピング。単一の符号位置を持つ」と説明されています。
ただし、代用符号位置に関しては、「Surrogate Character(代用文字)」の説明で「代用文字だと?代用符号位置を持つ符号化文字なぞありえん、こんな言葉を使うな」と名指しで言われているので、対応する符号化文字はありません。
また、「符号化文字の並び(Coded Character Sequence)」の説明に「非文字・予約済みの符号位置(ともに後述)も含んでよい」とあるので、これらも含んでいません。
このように、全ての符号位置が対応する符号化文字を持つわけではありません。
抽象文字(Abstract Character)
上の符号化文字と紛らわしいですが、Unicode側が図解を用意しています。また、単一の符号位置で表されないことがあります。
例えば、リング符号「˚」がついただけの「A」も、単位のオングストロームも同じ抽象文字ですが、これには複数個の表し方(符号化文字の並び)があります。
- U+00C5(Å):リング付きA
- U+212B(Å):オングストローム
- U+0041(A) + U+030A(̊)(Å):半角A + 合成用リング符号
このように、1個の抽象文字が符号化文字の並びによる複数通りの表し方があったり、一番下の例のように、1個の抽象文字が複数個の符号化文字で表されたりすることがあります。
全ての符号位置がこれや符号化文字に対応するとは限りません。(代用符号位置など)
次のものは抽象文字ではないとされます。
- 代用符号位置
- 非文字(後述)
- 予約済みの符号位置(後述)
割り当てられた文字(Assigned Character)
抽象文字に割り当てられている符号位置1個です。…って符号化文字と何が違うんですか?誰か教えて
非文字(Noncharacter)
次の符号位置です。
- U+FDD0~U+FDEF
- U+𝒏FFFE・U+𝒏FFFF(𝒏 ∈ {0, 1, 2, ⋯, 10₍₁₆₎})
予約済みの符号位置(Reserved Code Point)
別名:「未割り当て符号位置」(Unassigned Code Point)
今は文字が割り当てられていないものの将来割り当てられる可能性がある符号位置です。代用符号位置や非文字は今後も一切割り当てがないので違います。
U+32FF ㋿も、割り当て以前はこの予約済みの符号位置でした。(元々丸囲みのンが入ってもおかしくないが諸事情で未割り当てのままだった位置)
未割り当て文字(Unassigned Character)
抽象文字に割り当てられていない符号位置で、次に当てはまる符号位置です。
- 代用符号位置
- 非文字
- 予約済みの符号位置
すなわち、未割り当て文字 + 符号化文字(または抽象文字) = 全符号位置 という関係のようです。