コード日進月歩

しんくうの技術的な小話、メモ、つれづれ、など

UnicodeのCombining Character Sequenceの考え方とその正規化についてざっくりまとめる

Unicodeでポなどがホと半濁点の記号に分離されても一つの文字として見えてしまう現象に関してざっくりまとめる

TL;DR

  • Unicodeでは2つの文字符号位置を合わせて1つの文字を表す Combining Character Sequence という概念が存在する。
  • 日本語の濁音と半濁音にも「かな」と「濁音」をバラバラに扱い足し合わせることができる。そのためmacOSなどでは分解されてしまうケースがある。( に別れてしまう)
  • Unicodeでは正規化する方法が定義されており、合成後の文字が定義されている場合はその文字に変換される(は合成後の が1文字として定義されているので、そちらに変換できる
    • ただしこの正規化は漢字の扱いにおいて留意する点があるため、統一化したい場合に問題ないかを認識しておく必要がある

Combining Characterとは

Combining Characterとは何かしら他の意味のある文字と組み合わせて使うための文字のことを指す。日本語だと濁音(UnicodeコードポイントはU+0399)、英字だとウムラウト̈、コードポイントはU+0308 )などが当てはまる。

Combining Characterの使われ方とCombining Character Sequence

などのBase Characterとよばれるベースの文字とワンセットでつかうことで を表現することができる。このようにBase CharacterとCombining Charactorを合わせたものを Combining Character Sequence と呼ぶ。

また、のようにすでに「か」と「濁音」が一つとなってコードポイントが定義されているような文字のことをPrecomposed Characterと呼ぶ。

Combining Character Sequenceの問題点

上記のように組み合わせ次第で色々表現が可能となっているUnicodeの仕様だが、プログラムで解析するときに『』と『 +』は別ものになってしまうので、「ばか」という文字列だったら除外するのような処理をする場合に処理の書き方によってはCombining Character Sequenceで表現された文字はすり抜けてしまう危険がある。

1つの解決策としての正規化

Unicodeでは正規化という機構を用意しており、「分解」と「合成」という概念で処理をする。

「分解」はCombining Character Sequenceとして分解可能な文字を分解する処理、「合成」はCombining Character Sequenceが同一視できるPrecomposed Characterが存在すれば合成して一つの文字にすることを言う。

この「分解」と「合成」に関して分解後と分解前、合成後と合成前に同じものであるかのルールに関しても考え方が2つある。 ひとつは「Canonical Equivalent(正準等価)」という視覚的および機能的に等価な文字を等価と考える方法でもうひとつは「Compatibility Equivalent(互換等価)」というサンチーム を等価と考える広い解釈の2つがある。

正規化に関してはルールがいくつか存在するのですが、よく使われるのが Normalization Form Canonical Composition (略称:NFC) があり、これは「正準等価によって分解され、再度正準等価で合成される。」というもの、なのでひらがなやカタカナと濁音を一つの文字コードに寄せる場合にはこのNFCを利用すれば一律Precomposed Characterに変換することができる。

NFCを使うときの困りポイントであるCJK互換漢字

ここまでの説明だと「NFCで一律正規化をかければすべてPrecomposed Characterになるので解決」となりそうなのですが、NFCでは今回のCombining Character Sequenceとは別の観点の問題としてCJK互換漢字の問題があります。

CJK(ChinaJapanKorea)互換漢字は日本・中国・韓国の漢字の類似する文字を統合するCJK統合漢字という概念があり、その互換性がある漢字のことを指す。

よく語られるのは神の字で「ネ申」と書くのが普通だが「示申」と書くケースがあり、この2つはCJK互換漢字の関係にあり、すべてCJK統合漢字である「ネ申」と書く神に集約される関係にある。

NFCを使うとCJK互換漢字はすべてCJK統合漢字に変換されるので、厳密に漢字を扱いたい場合は何も考えずにNFCを行うと漢字が置き換わってしまうので気をつける必要がある。

補足:Combining Character Sequenceの日本語訳について

この Combining Character Sequence に関しては訳し方が年代によって変わっており、最近は「結合文字列」という表記をされることが多いが、物によっては直感的な認識を優先して「合成文字」と訳されるケースがある。

今回はその点に関して齟齬が起きづらいように英文ママの表現でざっくりまとめました。

詳しくは以下のリンクを参照すると日本語情報を調べるときに役立つと思います。

Unicode正規化 用語の混乱について 第4.2版 – ものかの

参考リンク

なお、未見なのですが文字コード悩まされる事が多いので下記の本を読んでみたくなりました…(財布の関係でまだ未入手)