よく忘れる基本的なアレコレ

2012.08.13

日本語文字エンコード

自分で用意した環境以外でのCGI作成&運用では色々と想定外の対応が必要になる。日本語文字エンコードに関してサーバの側で ShiftJIS に固定されているケースなどもあり(.htaccessで指定し直すという手もあるが)スクリプトはそれに対処できるように作っておかなくてはならない。

■ HTMLでの表示について

ShiftJIS でスクリプトを動かす設定にしてしまえば print される日本語文字コードも ShiftJIS になるようである。ShiftJIS でスクリプトを動かす設定にするには use 宣言すればよい。

# 扱う文字エンコードの調整
use encoding "shiftjis";
# HTMLとして表示
print "Content-type: text/html\n";

とりあえず上記上段のように書けば期待した動作はした。また管理者の設定にもよるのだろうが、この ShiftJIS 設定のサーバでは HTMLファイルとしての表示以外は認めていない(もしくは表示されるファイルの種類をきちんと明示させる仕様)らしく下段の print 文がないとエラーにされる。このためテスト用に簡単な文字列を出力しようとして執拗にエラーが返されてきたので混乱した。HTMLタグの文法(?)にミスがあってもエラーになった。

■ ファイルの書き出しと読み込み

スクリプトの動作を上記のように use 宣言して ShiftJIS に設定すると無指定で読み込みをする際の文字エンコードも同様となるが、ファイルの書き出しは ShiftJIS にはならない。

use encoding "shiftjis";
use Encode;
open (OUT, ">output.txt");
$lines = "まうまう";
# ShiftJIS へのエンコード
$lines_sjis = encode("shiftjis", $lines);
#print OUT $lines;
print OUT $lines_sjis;

文字列「まうまう」は encode を使わなければ ShiftJIS ではなく UTF8 で output.txt に書き出されるので注意が必要である。

>> Perl 5.8.x Unicode関連

Perl の文字エンコード処理についてはよくわからない部分もまだまだ多い。上記サイトは参考になるかもしれない。

■ 文字エンコードについて補足

備忘録的に簡単にメモしておく。読み込むファイル input.txt は UTF8 で書かれているものとする。

open(IN, "./input.txt");
while(<IN>){
$lines .= $_;
}
close(IN);
$lines_euc = encode("eucjp", decode("utf8",$lines));
#$lines_shiftjis = encode("shiftjis", decode("eucjp",$lines_euc));
#$lines_utf8 = encode("utf8", decode("shiftjis",$lines_shiftjis));
#$lines_euc = encode("eucjp", decode("utf8",$lines_utf8));
print $lines_euc;

特に指定しなければ日本語文字エンコードは EUCJP が選択され処理に使われる。UTF8 の文字列を EUCJP や ShiftJIS に変換する際、いくつかの記号や文字でエラーが起きるので注意が必要である。よく遭遇するのは書名の副題前後に入る長音記号に似た横棒によるもので、他に「糸圭」が一字になったものや仏語のアクサン付き文字などの所謂「外字」でも発生する。

配列の操作

■ push と shift

配列変数の操作では push で要素を挿入し、shift で要素を取り出すというのが基本である。

@array = ("まうまう","ほげほげ","ばるばるばる","ドドドドドド");
push(@array, "ドギューン");
shift(@array);

上記スクリプトの結果 @array の中身は push で $array[4] に「ドギューン」が加えられたあと、先頭 $array[0] の「まうまう」が shift によって消え、全体が前にずれて $array[3] が「ドギューン」となる。後入れ先だし方式である。

■ rand と splice

ランダムに要素を取り出したり消したりする場合には rand と splice を使う。

@array = ("まうまう","ほげほげ","ばるばるばる","ドドドドドド");
$num1 = @array;
while($num1--){
$num2 = @array;
$random_num = int(rand($num2));
push (@new_array,$array[$random_num]);
splice(@array, $random_num,1);
}
#@sorted = sort(@new_array);

@array の順番を入れ替えた配列変数 @new_array が出来る。$num1 を @array の要素数より少なく設定すれば、新しくできた配列は元の配列からランダムに要素を重複しないように抜き出したものとなる。重複しても構わない場合には splice を使った行はコメントアウトすれば良い。

■ split と join

スカラー変数から配列変数への変換には split を使う。逆は join で行なう。

#半角スペースで区分したリスト
$list = "まうまう ほげほげ ばるばるばる ドドドドドド";
@array = split(/ /, $list);
$new_list = join(' ', @array);

空白はテキストエディタで見え難いので間違いを避けるためにこうした処理の部分では見える記号を使い、入出力や表示の際に空白に置換するようにした方がいいかもしれない。

基本モジュール

■ CGI モジュール

フォームからCGIスクリプトに送られたデータの処理には「CGI」というモジュールを使うのが簡便である。現代の Perl に対応したサーバ環境では大抵使用可能となっている。

#CGIモジュールの使用
use CGI;
$object = new CGI;
#$object = CGI -> new; #データの取得
$data_1 = $object->param('data1');
$data_2 = $object->param('data2');

フォームから name = data1 である value を $data_1 に格納している。$data_2 の行でも同様のことをしている。

■ LWP モジュール

LWP::Simpleでのデータ取得についてはとりあえず get で内容を取り込める。

use LWP::Simple;
$document = get("http://ccoe.main.jp/");
$status = getstore("http://ccoe.main.jp", "index.html");
if (is_success($status)){
print $document;
}

getstore は指定したファイルに内容を格納し、戻り値としてHTTP応答コードを返す。is_success はHTTP応答コードが成功のとき True を返すようだ。以下のサイトが参考になるかもしれない。

>> get, head, getprint, getstore, mirror - 手続き型LWPインターフェース

LWP::UserAgent は LWP::Simple よりはもう少し色々なことができるらしい。

▼研究関連メモ目次へ戻る

Copyright(c)2005-2012 ccoe@mac.com Allrights reserved.