Perlでプログラムをするときに参考となるソース集です。
CGIにデータを渡す場合、URL(URI)エンコードする必要があります。
URLエンコードすると、特殊な文字や漢字は %xx (xx は16進数) となります。
以下の方法で、変数($arg)の内容をURLエンコードすることができます。
URLエンコードしなければならない文字は使わないのがベストですね。
#!/usr/local/bin/perl
$arg = $ARGV[0];
printf("arg=%s\n", $arg);
# URLエンコード
$arg =~ s/(\W)/sprintf("%%%02X", ord($1))/ego;
printf("arg=%s\n", $arg);
|
s/PATTERN/REPLACEMENT/egoで、置換を行なっています。
eは、式の右側の評価を行なう意味で、sprintfが評価されます。
gは、グローバルな置換で、見つかったものをすべて置換します。
oは、最適化指定ですので、おまじないみたいなものです。
正規表現 \W は、単語の構成文字以外にマッチします。
関数 ord EXPRは、EXPR の最初の文字の ASCII値を返却します。
また、URLエンコード処理は、unpack関数を利用しても記述できます。
# URLエンコード
$arg =~ s/(\W)/'%'.unpack("H2", $1)/ego;
|
CGIでは、URLエンコードされたデータをデコードする必要があります。
URLデコードすると、%XXとなっている部分が元の文字に戻ります。
以下の方法で、変数($arg)の内容をURLデコードすることができます。
#!/usr/local/bin/perl
$arg = $ARGV[0];
printf("arg=%s\n", $arg);
# URLデコード
$arg =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/ego;
printf("arg=%s\n", $arg);
|
また、URLデコード処理は、pack関数を利用しても記述できます。 chr関数は、perl4にはありませんので、perl4でも動作させる場合に使います。
# URLデコード
$arg =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/ego;
|
正規表現でよく使われる文字クラスとは、1対のブラケット[]の中に文字を並べたものです。 以下に文字クラスの例を示します。
| 文字クラス | 内容 | 簡略記法 | 簡略記法の否定形 |
|---|---|---|---|
| [0-9] | 数字1文字にマッチ | \d | \D,[^0-9] |
| [a-zA-Z0-9] | 英字か数字の1文字にマッチ | \w | \W,[^a-zA-Z0-9] |
| [ \r\t\n\f] | 空白,CR,TAB,LF,FFの1文字にマッチ | \s | \S,[^ \r\t\n\f] |
引数のURL($arg)を解析し、ホスト名($host)、ポート番号($port)、パス名($path)を取り出します。
URLのチェックや、URLの補完などに応用できます。
httpプロトコルのURLにのみ対応しています。
#!/usr/local/bin/perl
$arg = $ARGV[0];
printf("arg=%s\n", $arg);
# URLの解析
$arg =~ /(http:)?(\/\/)?([^:\/]*)?(:([0-9]+))?(\/.*)?/;
$host = $3;
if ($host eq "") {$host = 'localhost';}
$port = $5;
if ($port eq "") {$port = 80;}
$path = $6;
if ($path eq "") {$path = '/';}
printf("host=%s, port=%s, path=%s\n", $host, $port, $path);
|
メールアドレス($arg)を解析し、ユーザ名($user)、ホスト名($host)を取り出します。 メールアドレスのチェックや、メールアドレスの補完などに応用できます。
#!/usr/local/bin/perl
$arg = $ARGV[0];
printf("arg=%s\n", $arg);
# メールアドレスの解析
$arg =~ /(.*)(@)(.*)/;
$user = $1;
$host = $3;
printf("user=%s, host=%s\n", $user, $host);
|
パス名($path)から、ディレクトリ名($dir)、ファイル名($base)、拡張子($ext)を取り出します。
ファイル名は、拡張子を含まない、ベース名を返却します。
関数(split_path)として、利用できるようになっています。
# パス名の分離
# ($dir, $base, $ext) = &split_path($path);
sub split_path {
local($path) = @_;
local($dir, $file, $base, $ext);
$ext1 = '';
# ディレクトリ名の取得
if ($path =~ /(.*)\/(.*)/) {
$dir = $1.'/';
$file = $2;
} else {
$dir = './';
$file = $path;
}
# 拡張子の取得
if ($file =~ /(.*)\.(.*)/) {
$base = $1;
$ext = $2;
} else { # 拡張子なし
$base = $file;
$ext = "";
}
return($dir, $base, $ext);
}
|
変数($str)内の文字を、すべて大文字にしたり、小文字にしたりします。
# 文字列を小文字化 $str =~ tr/[A-Z]/[a-z]/; # 文字列を大文字化 $str =~ tr/[a-z]/[A-Z]/; |
数字には、8進数、10進数、16進数などがあります。 入力値($in)を出力値($out)に変換します。
# 10進->8進変換
$out = sprintf("%o", $in);
# 8進->10進変換
$out = oct($in);
# 10進->16進変換
$out = sprintf("%x", $in);
# 16進->10進変換
$out = hex($in);
|
ホスト名($host)からIPアドレス(@addrs)を取得します。 IPアドレスは、配列で返却されるため、ドットで区切られた形式にする場合は、printfなどで書式変換します。
#!/usr/local/bin/perl
# ホスト名の取得
chomp($host = `hostname`);
# IPアドレスの取得
($hname,$aliases,$addrtyp,$length,@addrs) = gethostbyname($host);
printf("host = %s\n", $hname);
# IPアドレスのドット表示
foreach $addr (@addrs) {
printf("addr = %s.%s.%s.%s\n", unpack('CCCC', $addr));;
}
|