その文字が JIS X 0208 に含まれるか? あるいは unicode.RangeTable の使い方
概要
世の中には UI こそ刷新されているけれど、バックエンドにはいにしえのコードが脈々と受け継がれているシステムがあります。たとえば、文字を入力すると「不正な文字が含まれています」とか警告されてはじかれたりするシステムに出会うことがあります。
きっと DB の文字コードが EUC であったり SJIS であったり、なんやかしあるのでしょう。
そんなときは大抵、Unicode な文字列を EUC とか SJIS などの JIS のコード体系に変換して、さらに Unicode に戻してやって、落ちてしまう文字を除外したりして対応したりするのではないでしょうか?
しかし、JIS のコード体系も拡張されたりして、現在はわりといろんな文字を採録していたりします。そうすると、コードを変換して対応しきれない文字を落とす、という方法もいまいち利用できないことがあります。
そんな背景があって、JIS 基本漢字などとよばれる JIS X 0208 に含まれる文字であるかどうかの判定をおこなうライブラリを用意しました。
JIS X 0208 JIS基本漢字
Wikipedia によれば JIS X 0208 とは、下記のようなコード体系です。
JIS X 0208は、日本語表記、地名、人名などで用いられる6,879図形文字を含む、主として情報交換用の2バイト符号化文字集合を規定する日本産業規格 (JIS) である。現行の規格名称は7ビット及び8ビットの2バイト情報交換用符号化漢字集合 (7-bit and 8-bit double byte coded KANJI sets for information interchange) である。1978年にJIS C 6226として制定され、1983年、1990年および1997年に改正された。JIS漢字コード、JIS漢字、JIS第1第2水準漢字、JIS基本漢字などの通称がある。
初期からある日本語の文字コード体系で、一番基本的な部分、と思っていればだいたいよさそうです。
もちろん、JIS X 0208 の文字はすべて Unicode に含まれています。
JIS X 0208 の文字を洗い出す
JIS X 0208 に含まれる文字については、JIS X 0213 コード表(全コード) のうちの基本漢字の部分を参考にさせて頂きました。
こいつを Go の unicode.RangeTable
に変換していきます。unicode.RangeTable
は、文字集合を表現するための型で、文字の範囲を小さい順に並べたテーブルになっています。このテーブルを作っておくと、unicode.Is(range *RangeTable, r rune) bool
という関数で、ある文字が定義したテーブルに含まれるかをチェックできます。
作り方は、上述のコード表の漢字を SJIS コードで表現して、そのバイト配列を Unicode に変換して対応するコードポイントに変換していきます。変換したコードポイントを小さい順にソートして、それを unicode.RangeTable
に変換すれば完成です。
JIS X 0208 な文字列に変換する
余談ですが、Go の文字列はバイト配列であればよくて、かならずしも正しい utf8 な配列でなくてもよいことをご存じでしょうか?そんな文字列を扱うために strings
パッケージには strings.ToValidUTF8(s, replacement string) string
なる関数が用意されています。この関数は与えられた文字列 s
に正しくないバイト列があったときには指定された replacement
で置き換えて、utf8 としてただしい文字列を返してくれます。
同じように。JIS X 0208 として正しい文字だけを含むようにする ToValidateJISX0208(s, replacement string) string
を用意しました。
だから?
これといってオチはありません。
Unicode 全盛の現代においても JIS X 0208 で生き続けているシステムと、それをメンテしている開発者がいると思うと感慨深いものがあります。
そんなシステムに出会ったときにはそっと文字コードを変換して対応してあげて欲しいです。
unicode.RangeTable
は結構便利なので、機会があったら使ってみてください。
Happy hacking!
Discussion