ASH | サーバ | セキュリティ | Linux | FreeBSD | DB | Web | CGI | Perl | Java | XML | プログラム | ネットワーク | 標準 | Tips集

PerlプログラミングTips集(変換編)

 Perlでプログラムをするときに参考となるソース集です。

URLエンコード/デコード処理

URLエンコード処理

 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;

URLデコード処理

 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の解析処理

 引数の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);

IPアドレスの取得処理

 ホスト名($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));;
}


Copyright (C)1995-2002 ASH multimedia lab.
mail : info@ash.jp