今ならLingua::JA::Regular::Unicodeが第一選択肢ですが、こういう方法もあるということで。
Perl で半角カナと全角カナの変換をする : Serendip - Webデザイン・プログラミングPerl を使って半角カタカナと全角カタカナの変換をするスクリプトを、標準モジュールの Encode.pm と Unicode::Japanese と Lingua::JA::Regular::Unicode を使ってそれぞれ変換スクリプトを書いてみる。
CORE Moduleのみを使うという縛りをかけています。
#!/usr/bin/perl use 5.008001; use strict; use warnings; use utf8; use charnames ':full'; use Unicode::Normalize; { my $hankaku = "\x{FF9E}\x{FF9F}"; my $zenkaku = "\x{3099}\x{309A}"; for my $o (0xFF61 .. 0xFF9D){ $hankaku .= chr $o; my $n = charnames::viacode($o); $n =~ s/HALFWIDTH\s+//; $zenkaku .= chr charnames::vianame($n); } *tr_h2z = eval "sub { local \$_ = shift; tr/$hankaku/$zenkaku/; \$_ }"; *tr_z2h = eval "sub { local \$_ = shift; tr/$zenkaku/$hankaku/; \$_ }"; sub han2zen { NFC(tr_h2z(shift)) } sub zen2han { NFC(tr_z2h(NFD(shift))) } sub hira2kata { local $_ = shift; tr/\x{3041}-\x{3096}/\x{30A1}-\x{30F6}/; $_; } } binmode STDOUT, ":utf8"; local $\ = "\n"; print zen2han(hira2kata("「ぽげむたぴぎゃみにょーん」って最初に言ったのは?")); print han2zen("ウソダドンドコドーン");
なんだか呪文じみていますが、以下を見れば何をやっているのか何となくご理解いただけるのではないでしょうか。
FF61 HALFWIDTH IDEOGRAPHIC FULL STOP FF9D HALFWIDTH KATAKANA LETTER N .... FF9E HALFWIDTH KATAKANA VOICED SOUND MARK FF9F HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK 3099 COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK 309A COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK 3041 HIRAGANA LETTER SMALL A .... 3096 HIRAGANA LETTER SMALL KE 30A1 KATAKANA LETTER SMALL A .... 30F6 KATAKANA LETTER SMALL KE
半?濁点の処理を、Unicode::Normalizeでやっているのが工夫のしどころでしょうか。
で、業務連絡>id:tokuhirom。
Lingua::JA::Regular::Unicode というモジュールをつくりました - TokuLog 改めB日記同じことができるモジュールとして id:takefumi 作の Lingua::JA::Regular というものがあるのですが、これは EUC-JP 前提なので、昨今の「内部コードは flagged utf8」という流れからすると、無駄に二回文字コードの変換をはしらせなくてはならず、使いづらかったので、新たに unicode 前提でつくりなおしました。
Lingua::JA::Regular::Unicodeの中味は正しくtr///のお化けなのですが、残念なことに、Perl 5.8.0のtr///はUnicode的にbuggyで非推奨です。CodeReposのrepoは直しておいたので、あとはよろしくです。あと、Module::Installを使っているのはモダンで結構なのですが、CodeReposの方にincディレクトリがなくて、trunkから直にperl Makefile.PLできなくなっているようです。CPANの方はOKなのですが。
これに限らず、Unicode-savvyなPerlの事実上の最古Versionは5.8.1と覚えておくとよいでしょう。
ダンザパールモンガー
"\x{0100}=ccc" =~ /.*?=(a|b)/;
で、Malformed UTF-8 character エラーになります。
バージョンは 5.8.8, 5.10.0 の両方。