Home > CGI > JEncode

JcodeライクなEncodeのWrapper

はじめに

 Dan Kogai氏によりJcode 2.0がリリースされました。これをもちましてJEncodeはその役目は終えました。一応このページは残しておきますが、今後はJcode 2以上をご利用ください。Perl5.8.1以降はEncodeのラッパーとして機能します。


EncodeとJcode

 Perl5.8以降の標準モジュールにEncodeがあります。Perl5.8の目玉でもありまして、他言語の取り扱いを容易に可能にしてくれる有り難いモジュールです。これまで日本語を扱おうとすると歌代和正氏の jcode.plやDan Kogai氏のJcode.pmのお世話になっていたはずです(EncodeはDan Kogai氏が開発維持しています)。あるいはUnicode::Japanese(さわたりみかげ氏 山科氷魚氏)など。

 EncodeはJcodeとはメソッドも関数も違います。5.8とそれ以下の環境で同じプログラムを走らせたい時に、諸般の事情で5.8の方にJcodeを入れることが出来ない場合、あるいは面倒くさい場合(いいのかそんなで?)、Encodeがあるかないかで処理を分けることになるのですが、これはソースがごちゃごちゃしてあまり嬉しくありません。そこでEncodeのラッパーをつくって、インターフェースだけJcodeのそれと一緒にしてしまうことにしました。これをとりあえずJEncode.pmと名付けます。

Source

JEncode.pm v1.33
テスト test.pl (2004-09-29)

v.1.12以前で$j->set($str)->h2zなどとしたときに、$strの値自体まで変更してしまいました。v.1.13以降修正されています。v.1.19まで$j->set(\$str)->tr(...)しても$strの値が変更されていませんでした。1.20で修正しました。1.3でmime_encodeをiso-2022-jpにすることができるようになりました。1.3までmimde_encodeが正しくありませんでした。1.31で修正されました。1.33 ISO-2022-JP版mime_encodeの結果がJcodeのものと同等になりました。

 Jcodeに比べて、Encode::Guessの文字コード判定は、短い文字列に対して正しく出来ないことが多々あります(理由)。そのため、v.1.08以降、補助的な判定をつけてみました。これでかなり正しく判定されますが、いわゆる半角カナや一部の記号だけからなる文字列等の判定には失敗するでしょう。1.18で少し精度が高まったと思います。矢印、罫線、一般句読点を判定できなかったのを1.19で修正。1.20〜1.22でさらに修正(参考)。そろそろ実用に耐えると思います。

使い方

 下記の留意点を除いてJcode.pmのそれとほとんど同じですので、Jcode.pmのドキュメントをご覧下さい(和訳)。関数はgetcodeとjcodeがインポートされます。convertはJEncode::convertで呼び出せます。JEncode.pmのファイル名をJcode.pmに変更し、最初の行のpackage JEncode;package Jcode;に変更すれば、Jcodeを使っていたコードがEncodeにおきかえられるという寸法でさあ……たぶん。

 mime_encodeの結果をiso-2022-jpのMIME-encodeで受け取りたい場合は予め$JEncode::MIME_HEADER_ISO2022JP = 1;としておきましょう。

オリジナル部分

 jfold禁則処理

    my @kinsoku = qw(。 、);        # 禁則単語(EUC-JP)
    $j->jfold(10, "\n", \@kinsoku); # 配列リファレンスで渡す

 matchsメソッド(パターンの日本語はEUC-JP)。matchの返値はperl組み込みのm//と同じです。このmatchやsでは\wは日本語一文字に対応し、句読点、全角スペースなどは\Wとなります。正規表現のオプションはimsxに対応しています。置換ではさらにgオプションを引数に取ることができます(第四引数)。パターンを与えないと、直前のパターンが再利用されますので、これを活用して処理速度を上げることも可能でしょう。

    if( $j->match('文字 # オプションも可能','x') ){
        print "Match!";
        $word = $j->match('(\w+)');               # /(\w+)/ に同じ。但し日本語対応!
    # match は m でもよい
        @array = $j->m('(..)は(テスト)ですよ。'); # @array = $str =~ /(..)は(テスト)ですよ。/
    }

    $j->s('test','ok',i,'g');     # s/test/ok/ig に同じ

    $j->s('テスト','実験',undef,'g'); # s/テスト/実験/g に同じ

    $j->match(); # 引数を与えない場合は直前のものが使われる(sと共通)
                 # この場合は $j->match('テスト') と同じ

 さらに$j->s()というふうに、パターンも置換文も無しで呼び出すと、直前にs()で使われたパターンがそのまま利用されます。

    my $j = JEncode->new->set('');   # オブジェクト生成
    $j->s('。','にゃ。',undef,'g');  # 一度だけパターンを生成する
    open(FILE,'neko.txt') or die $!;
    while(my $line = <FILE>){
        $j->set($line)->s();         # 一切引数無しで呼び出す
    }
    close(FILE);

留意点

その他

 いずれEncodeのラッパーもかねるJcode-2.0がでるそうなので、JEncode作成はただの徒労に終わっています。参考

openlab.jcode5 perl//Encode

ページの先頭