その文字が JIS X 0208 に含まれるか? あるいは unicode.RangeTable の使い方

2 min read読了の目安(約2000字

概要

世の中には UI こそ刷新されているけれど、バックエンドにはいにしえのコードが脈々と受け継がれているシステムがあります。たとえば、文字を入力すると「不正な文字が含まれています」とか警告されてはじかれたりするシステムに出会うことがあります。

きっと DB の文字コードが EUC であったり SJIS であったり、なんやかしあるのでしょう。

そんなときは大抵、Unicode な文字列を EUC とか SJIS などの JIS のコード体系に変換して、さらに Unicode に戻してやって、落ちてしまう文字を除外したりして対応したりするのではないでしょうか?

しかし、JIS のコード体系も拡張されたりして、現在はわりといろんな文字を採録していたりします。そうすると、コードを変換して対応しきれない文字を落とす、という方法もいまいち利用できないことがあります。

そんな背景があって、JIS 基本漢字などとよばれる JIS X 0208 に含まれる文字であるかどうかの判定をおこなうライブラリを用意しました。

https://github.com/ikawaha/encoding

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!