Unicode::Normalize で遊ぶ
Unicode の規格では,文字の合字(リガチャ等)等を統一的に扱えるように,「正規化」という処理が仕様として定まっています。この正規化処理のうち「互換性分解」という処理を行うと副作用として半角カナを全角カナに変換できます(逆に全角カナ→半角カナはできません)。
#!/usr/bin/perl use strict; use utf8; use Encode; use Unicode::Normalize; my $src = 'ポンジュース'; my $dst = Unicode::Normalize::NFKC($src); print Encode::encode('utf8', "${src} => ${dst}\n"); # OUTPUT is: ポンジュース => ポンジュース
Unicode の正規化についてはperl5.8のUnicodeサポート および http://homepage1.nifty.com/nomenclator/unicode/normalization.htm が詳しいです。特に後者に
と書いてあります通り,本来はたとえばデータベース等で同じようなフィールド値(ⅢとIIIとか)を検索したい場合に用いるものですので,むやみやたらと用いるべきではないそうです。ウェブアプリでのフォーム入力は適用範囲としてまぁまぁ当てはまる気もしますが。
UAX #15によれば、NFKDおよびNFKCは、互換分解によって多くの書式上の差異をなくしてしまうため、任意のテキストに対して無闇に用いてはいけない (Normalization forms KC and KD must not be blindly applied to arbitrary text.) が、大文字・小文字を揃える処理のように考えるのが良く、例えば、特定の文脈においてテキストの核心の意味を特定したり、必ずしも適切ではないテキストを修正したりするのに有用とされています。
さて。
普通リガチャというと欧文文字でのアセント付き文字やfiなどを指しますが,日本語でも複数の文字を組み合わせた記号を使ったりします。たとえば,「㈱」とか。
こういった文字たちを,互換分解するとどうなるのか,ためしてみました。
#!/usr/bin/perl use strict; use utf8; use Encode; use Unicode::Normalize (); my @chars = ( "\x{00a9}" => 'copyright', "\x{00be}" => '4分の3', "\x{00ab}" => '<<', "\x{2103}" => '℃', "\x{2121}" => 'TEL', "\x{2122}" => 'トレードマーク', "\x{2166}" => 'ローマ数字 大7', "\x{2177}" => 'ローマ数字 小8', "\x{2460}" => '丸付き数字 1', "\x{2475}" => '括弧付き数字 2', "\x{248a}" => '3.', "\x{249f}" => '(d)', "\x{24ba}" => '丸付き英字 E', "\x{24d5}" => '丸付き英字 f', "\x{266d}" => '音楽記号 フラット', "\x{266f}" => '音楽記号 シャープ', "\x{2749}" => 'balloon spoked asterisk', "\x{277c}" => '黒丸数字 7', "\x{3004}" => 'JISマーク', "\x{3020}" => 'ポストンくん', "\x{3036}" => 'マル〒', "\x{3037}" => 'ダブルエックス', "\x{3227}" => '(八)', "\x{3240}" => '(祭)', "\x{3299}" => 'マル秘', "\x{32c5}" => '6月', "\x{33e4}" => '5日', "\x{32da}" => 'マルサ', "\x{334c}" => 'メガトン', "\x{3370}" => '24点', "\x{337b}" => '平成', "\x{337f}" => '株式会社', "\x{3393}" => 'ギガヘルツ', "\x{33a0}" => '平方センチメートル', ); while (@chars) { my $chr = shift @chars; my $desc = shift @chars; my $nfkc = Unicode::Normalize::NFKC($chr); next if $chr eq $nfkc; print Encode::encode('utf8', "${chr}\t${nfkc}\t${desc}\n"); }
こんなにも使わなさそうな(失礼)記号がたくさん定義されているんだなとも思いますが,これの実行例は
¾ 3⁄4 4分の3 ℃ °C ℃ ℡ TEL TEL ™ TM トレードマーク Ⅶ VII ローマ数字 大7 醞 viii ローマ数字 小8 ① 1 丸付き数字 1 ⑵ (2) 括弧付き数字 2 ⒊ 3. 3. ⒟ (d) (d) Ⓔ E 丸付き英字 E ⓕ f 丸付き英字 f 〶 〒 マル〒 ㈧ (八) (八) ㉀ (祭) (祭) ㊙ 秘 マル秘 ㋅ 6月 6月 ㏤ 5日 5日 ㋚ サ マルサ ㍌ メガトン メガトン ㍰ 24点 24点 ㍻ 平成 平成 ㍿ 株式会社 株式会社 ㎓ GHz ギガヘルツ ㎠ cm2 平方センチメートル
ブラウザですべてを正しく表示できない可能性も高いので,UTF-8 が使えるターミナルをお持ちの方はご自分で試して頂けるとより楽しめると思います。
「㈱」とか「Ⅲ」とか入力で使うなよ!とお怒りの(昔ながらの?)業務アプリ制作者の方や,検索システムを構築してるという方は,気にとめておくとみんなハッピーになれるかもしれません。