Unicode 難しい
Unicode の扱いには色々と難しいところがある。
私は最近になって、いろいろと勉強している。
なので、以下の内容には Unicode 初心者によるひどい間違いがあるかもしれない。
自分は Unicode の正規化の違い (NFC, NFD, NFKC, NFKD) でややこしい点については知っていたのだけど、
それとは別のレイヤの話で、タイ文字・アラビア文字・デーヴァナーガリー文字などを視覚的に文字数を数える時は Grapheme というさらに上の層での数え方が必要らしい。
参考: 文字数をカウントする7つの方法
Grapheme
つまり
- プログラミング言語で普通に文字数を数えると Code point の数になる。
- 実際には視覚的に 1 つの文字が、複数の Code point によって構成されている場合がある。
- 視覚的に正しい 1 文字の単位が Grapheme cluster
らしい。
では Python では?
では Python では Grapheme cluster を数えるのにどんなツールがあるか ?
Python の標準ライブラリである unicodedata には含まれていないようだった。
答え
uniseg というパッケージがあるらしい。
なお、この記事では主に Python 3 での例を示す。
(Python 2 と Python 3 での unicode, str, bytes の扱い方の違いについては触れない。触れると横道に大きくそれる。)
インストール方法
$ pip install uniseg
使用例
>>> import uniseg.graphemecluster
>>> graphme_split = lambda w: tuple(uniseg.graphemecluster.grapheme_clusters(w))
>>>
>>> phrase = 'กินข้าวเย็น' # タイ語で夕食を食べる、という意味のフレーズらしい
>>> len(phrase.encode('UTF-8')) # UTF-8 での bytes
33
>>> len(phrase) # Code Points
11
>>> len(graphme_split(phrase)) # Graphme clusters
8
という具合。
他にも
uniseg は word や sentence 単位での分かち書きを備えているらしい。
さすがに space で切るらしいので膠着語である日本語の分かち書きまではできないようだ。