« 「御殿場プレミアム・アウトレット」のぞいてきました | トップページ | 読みにくいサービス名・商品名をちゃんと読む »

2007年10月20日 (土)

PerlのNKFモジュール(NKF.pm)のつたない解説

初めてのPerl
初めてのPerl
posted with amazlet at 08.10.11
ランダル・L. シュワルツ トム フェニックス
オライリージャパン
売り上げランキング: 2957
おすすめ度の平均: 4.5
5 素晴らしきPerlの世界への案内
5 読み物としても十分面白い
5 定番書
5 初心者も持っておきたい一冊
5 CGI言語としてのPerl


今日は珍しくお仕事系の話。
先日メール関連処理のために使ったPerlのNKFモジュールが非常に使い勝手が良かったので、ご紹介です。
僕と同様、Perl付属のEncodeライブラリに四苦八苦している方は参考になると思いますよ。


NKF.pmについて
NKF.pmは文字コード変換プログラム nkf のPerlモジュール版です。
往年のPCユーザは「nkf」と聞くと懐かしく感じるのでは。
unix系マシンとWindowsマシンでテキストファイルをやり取りしたりする上では必須のアプリでしたよね。

このnkf、地道にバージョンアップを続けていて、この記事を書いている時点での最新版は「Ver2.0.8b」です(安定板は2.0.7)。nkfは知らないうちに非常に便利なオプションが追加されていて、これ1つでメール周りの処理を簡単に行うことができるようになっています。
また、同時にPerlモジュール版もバージョンアップを続けていて、nkfの便利な機能をPerlのプログラム内で簡単に利用できるようになっています。


なぜNKF.pmか?
Perlの文字コード変換関連には様々なモジュールがあります。
Perl標準のEncodeライブラリのほか、Jcode や jcode.pl(最近は使わないかな)などなど。
ですが、その中でNKFを選んだ理由は下記です。

・必要な十分な機能
文字コード変換(utf8、半角カナ変換対応)、MIMEエンコード/デコード、マッピング不可文字の変換(「〓」で表現)など、Perlで日本語を扱うときに必要そうな機能はたいてい入ってます。
これらがモジュール1つで賄えるところが便利。

・バイナリ版nkfとの親和性
基本的な使い方は $result = nkf("オプション",$source) という感じ。で、オプションの指定のしかたはバイナリ版のnkfと共通です。
なので、昔からnkfを使っている人にとってはわかりやすいです。

・見通しがいい
Perl標準のEncodeライブラリは非常に強力なのですが、「utf8フラグ」などの概念を理解しないと難しいです。僕もひととおりは勉強したつもり…なのですが、いまだにencodeを2回呼んでしまっておかしくなったりというミスが多いです。
# もちろん僕の技術力によるところが大きいんですけどね。
NKFモジュールはutf8フラグなどを気にしなくていいので、ミスしにくいというところがいいと思います。


利用前の準備(宣言)
まずは準備です。
Perlプログラム内で利用するため、useで宣言しましょう。

use NKF;

はい準備完了。簡単ですね。
おっと、インストールはこれ以前に済ませて置いてくださいね。
マニュアルどおりやれば問題ないはずです。


主な使い方
主な使い方は下記のような感じ。
サンプルを見たほうが早いですよね。

■$input の文字列をShift-jisに変換
基本的に入力文字列の文字コードは自動判別するので、変換したい先の文字コードのみをオプションで指定します。

$output = nkf("-s",$input);

これで $output に $input をShift-jisに変換した文字列が入ります。

■ヘッダのMIMEエンコード、デコード
メール内の日本語のヘッダ(FromやSubjectなど)はMIMEでエンコードする必要がありますが、NKFモジュールを使うとエンコード後文字列の行分割までひっくるめてちゃんと処理してくれます。

(1)エンコード

$subject = nkf("-M","【転送】ガジェットWatchでこんな記事見つけました");

これで$subjectにMIMEエンコードされた文字列が入ります。

(2)デコード

$subject_decoded = nkf("-m",$subject);

MIMEエンコードされた $subject をデコードし、普通の日本語として $subject_decoded に格納します。同時に出力文字コードの指定も可能なので、いきなりEUCにすることもできます。
(単純にデコードしただけだとJISになりますよね。)

■$input の文字コードの推定
文字コードの推定をする場合はバイナリ版nkfとちょっとやり方が違います。
一旦nkfモジュールをその文字に対して適用したあとで、「inputcode()」関数を使います。

nkf("",$input);
print inputcode(); # 「EUC-JP」「ASCII」などの文字列を表示

inputcode()関数で、最後に評価した文字列の推定文字コードを取得できます。

■$input に含まれる「まずそうな文字」をつぶした上でEUC変換
ケータイの絵文字など、JISで表現できない文字を「〓」に変換します。
当然その部分は読めなくなりますが、変なコードと認識して誤動作しちゃう~という最悪の状態は避けられます。

$output = nkf("-Ie",$input);

「〓」に変換するのが「-I」、EUCで出力するのが「-e」オプションです。
オプションは上記のように重ねて「-Ie」などと書くことができます。


まとめ
このほかにもNKF2.0.7ではバイナリデータもMIMEストリームに変換できる( = 添付ファイルが簡単に作れる)など、便利な機能が増えています。
本当にちゃんとしたメール処理を行うならMIME::Entityなどを利用することになると思いますが、そこまでの機能が不要で簡単に書くならNKF.pmモジュールは非常に見通しがいいと思います。

Perl5.6以降の日本語関連で困っている方がいればぜひご参考に。
あ、一応正しいつもりで書いていますが、上記コードが間違っていたらぜひともご指摘ください。


関連サイト
Project Info - nkf Network Kanji Filter (SourceForge)
現在のnkfプロジェクトです。
ソースのダウンロードやマニュアルの取得はここから。

|

« 「御殿場プレミアム・アウトレット」のぞいてきました | トップページ | 読みにくいサービス名・商品名をちゃんと読む »

プログラム(Perl・HTML・JavaScript)」カテゴリの記事

コメント

Encodeモジュールの場合でもEncode::from_to()を使えば「utf8フラグ」の概念が不要なので便利です。モジュールを追加インストールできない環境でこの方法で助かったことがあります。ご参考までに。

投稿: ワインパン | 2015年11月27日 (金) 17:20

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/153129/16798769

この記事へのトラックバック一覧です: PerlのNKFモジュール(NKF.pm)のつたない解説:

« 「御殿場プレミアム・アウトレット」のぞいてきました | トップページ | 読みにくいサービス名・商品名をちゃんと読む »