連想配列(ハッシュ)への取り込み |
0x00 から 0x20 のコントロール文字
0x7F から 0xFF のトップビットが立っているもの " # % ; < > ? { } | \ ^ ~ ` [ ] |
これらに加えて & = はデータの区切り文字に使われるので、これらがデータ中に現れる場合もエンコーディングされています。さらに空白文字は + に変換され、データ中の + はやはり16進数値にエンコーディングされています。
デコードする際は特にこれらの文字を気にせずに %XX が現れたら元の文字に変換します。
具体的には、例えばSJISの'あ'という文字は16進数値で0x82 0xA0であり、%82%A0とエンコードされています。これをデコードするには、
#!/usr/bin/perl $before = '%82%A0'; # SJISの「あ」 # 先頭の%を除いて16進数を取り出す @x = ($before =~ /%([A-Fa-f0-9][A-Fa-f0-9])/g); # 16進数を10進数にする @x = grep { $_ = hex } @x; # 16進数値を文字に変換 $after = pack("cc", @x); print "before=$before, after=$after\n"; |
これを一気に行うと
$_ = $before; $after =~s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("c", hex($1))/; |
とすることができます。
サンプルスクリプトでは、デコードしたものを
なお、日本語に関する処理は「日本語コードの取り扱い」の項を参照してください。
# # parseInput(encoding) # <IN> encoding: 日本語コード(jis|sjis|euc) # <OUT> Name=>Val のハッシュ(グロブ) # sub parseInput { my($encoding) = @_; my($method) = $ENV{'REQUEST_METHOD'}; local($query, @in, $key, $val); # 日本語が必要な場合は jcode.pl を取り込む require 'jcode.pl' if $encoding; # GETメソッドかPOSTメソッドかを判別する if ($method eq 'GET') { $query = $ENV{'QUERY_STRING'}; } elsif ($method eq 'POST') { read(STDIN, $query, $ENV{'CONTENT_LENGTH'}); } # 入力データを分解する local(@query) = split(/&/, $query); # Name=Val を $in{'Name'} = 'Val' のハッシュにする。 foreach (@query) { # + を空白文字に変換 tr/+/ /; # Name=Val を分ける ($key, $val) = split(/=/); # %HH形式を元の文字にデコードする。 $key =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("c", hex($1))/ge; $val =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("c", hex($1))/ge; $val =~ s/\r\n/\n/g; # 日本語コードが指定されている場合は変換する。 jcode'convert(*key, $encoding) if ($encoding); jcode'convert(*val, $encoding) if ($encoding); # 連想配列(ハッシュ)にセット $in{$key} = $val; } # 連想配列のグロブを返す return *in; } |