2005年9月21日 (水)

Perl備忘録 -文字列成型-

掲示板CGIなどユーザが入力した文字を使う場合、文字化けを防いだり処理に適合させるため、文字列成型が必要となる事がある。


・半角カナは文字化けする事があるため、全角カナに変換する方が無難である(Shift-JISの場合)。

  &jcode'h2z_sjis(\$sorce);    #半角カナ→全角カナ

※ jcode.plが必要


・入力内容をファイル名にする等、英数字を半角で統一したい場合

  local($han) = "0123456789"
    ."abcdefghijklmnopqrstuvwxyz"
    ."ABCDEFGHIJKLMNOPQRSTUVWXYZ";

  local($zen) = "0123456789"
    ."abcdefghijklmnopqrstuvwxyz"
    ."ABCDEFGHIJKLMNOPQRSTUVWXYZ";

  &jcode'tr(*sorce,$zen,$han);  #全角英数→半角英数


・改行コードはHTMLに出力しても表示上の改行にならないので、改行を表すbrタグに変換する

  #改行コードを変換
  $sorce =~ s/\r\n/<br>/g;
  $sorce =~ s/\n/<br>/g;
  $sorce =~ s/\r/<br>/g;


・入力内容にHTML上意味のある文字(タグなど)を含むと、表示を崩したりセキュリティの問題があるのでそれぞれを表す記号(&xxx)に変換する。

  #HTMLで意味のある文字列を変換する
  $sorce =~ s/"/&quot;/g;
  $sorce =~ s/&/&amp;/g;
  $sorce =~ s/</&lt;/g;
  $sorce =~ s/>/&gt;/g;


・前後の全角半角スペースを削除(Shift-JISの場合)

  local($1) = "";
  local($Zspace_sjis) = '(?:\x81\x40)';
  local($oneByte_sjis) = '[\x00-\x7F\xA1-\xDF]';    #1バイト SJIS文字
  local($twoBytes_sjis) =
    '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';  #2バイト SJIS文字
  local($character_sjis) = "(?:$oneByte_sjis|$twoBytes_sjis)";

  $sorce =~ s/^(?:\s|$Zspace_sjis)+//o;            #前
  $sorce =~ s/^($character_sjis*?)(?:\s|$Zspace_sjis)+$/$1/o;  #後

※ jcode.plが必要


おまけ

・数字3桁ごとに","(カンマ)を入れる(EX.10000→10,000)
  while($sorce =~ s/(.*\d)(\d\d\d)/$1,$2/){}

| | コメント (0) | トラックバック (0)

2005年9月18日 (日)

Perl備忘録 -CGI呼び出し-

掲示板CGI等でFORMより送信された内容は、「引数名1=値1&引数名2=値2・・・」という形で渡されるため、CGIで処理を行う場合に、各引数を分離する必要がある。

※ 引数名1,引数名2・・・・の引数名は<form>~</form>内の<input>タグのname属性に指定した文字列になる。


まず、CGIに渡される形式は"GET"と"POST"という形式があるが下記のように記述すれば、GET,POST共に対応できる。

    # 引数を$bufferに格納する
    if($ENV{'REQUEST_METHOD'} eq "POST") #POSTの場合
    {
        read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
    }
    else #GETの場合
    {
        $buffer = $ENV{'QUERY_STRING'};
    }

POSTで送信された場合は、標準入力に引数が書き込まれるため「read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});」としている。POSTの場合読み取りサイズ指定が必要なので「$ENV{'CONTENT_LENGTH'}」で指定している。

GETで送信された場合は、引数はURIとしてURLに引数が付加された形で送られてくるため、「$ENV{'QUERY_STRING'}」をそのまま格納している。


下記の記述で引数を分離する。引数の形式は「引数名1=値1&引数名2=値2・・・」という形で渡されるため、まず「local(@pairs) = split(/&/,$buffer)」で変数毎に分離した引数リストを作り、foreachで各引数要素に「local($name, $value) = split(/=/, $pair);」して、各引数名と値に分離している。

    #引数解析
    local(@pairs) = split(/&/,$buffer);
    local($pair);
    foreach $pair (@pairs)
    {
        local($name, $value) = split(/=/, $pair);
        #デコード処理
        $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

        &jcode'convert(*value,'sjis');

        #引数を格納
        $FORM{$name} = $value;
    }

尚、掲示板CGI等、日本語(2バイト文字)での送信がある場合、引数に渡される文字列はURIエンコードされて渡されるため、処理を行う前に元の文字列に戻す(デコード)する必要がある(ここではShift-JISに変換している)。

変換処理にはjcode.plを利用しているため、予め「require './jcode.pl';」する必要がある。

| | コメント (0) | トラックバック (0)