濁点・半濁点を分離する関数の作成中、Unicode上での濁点・半濁点の扱いに戸惑ったのでメモ書き。
NFDとNFC
Unicodeの中にも、
NFC:Normalization Form Canonical Composition (合成済みの文字)
NFD:Normalization Form Canonical Decomposition (複数文字を結合した文字列)
と種類があるらしい。
JavaScriptの文字列はデフォルトではNFCとして扱われるが、
'文字列'.normalize('NFD')
でNFDに変換できる。
表記の違い
それぞれencodeURIでエンコードすると分かりやすい。
nfc.js
console.log( encodeURI('か'.normalize('NFC')) );
//%E3%81%8B
console.log( encodeURI('が'.normalize('NFC')) );
//%E3%81%8C
nfd.js
console.log( encodeURI('か'.normalize('NFD')) );
//%E3%81%8B
console.log( encodeURI('が'.normalize('NFD')) );
//%E3%81%8B%E3%82%99
NFCでは「か」と「が」は別の文字と区別されているのに対して、NFDでは「か + ゛」といったように濁点用の文字(%E3%82%99)が用意されていることが分かる。
ちなみに半濁点「゜」(%E3%82%9A)もあった。
一応結果
最初は10行くらいあったdakuten関数が1行にまとまってかなりのダイエット成功。
NFD/NFCとか聞いたこともなかったので他の人がハマらないようお役に立てると幸いです。
引用
参考にさせて頂きました。より詳しい部分が解説されています。