新・元地方の中規模印刷会社で苦悩するWebデザイナー改めWebディレクターの日記

自由な20代、窮屈な30代を経て、遂に40代になっちまったWebディレクター&パソコン講師の覚書と思う言(こと)。略称【ちほちゅう】

*

perlの文字コード変換を詳しく調べてみる

   

  • このエントリーをはてなブックマークに追加

1年以上前の記事です。内容が古い可能性があります。

最近、perlプログラミングを本格的に始めたのですが、
文字コード変換がイマイチ良く分かってない。
そこで、一つ一つを細かく調べてみた。

スポンサーリンク
 

まず最初に↓これが分かりません。調べてみました。

if ($ENV{'REQUEST_METHOD'} eq "POST") {
  read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}
else { $buffer = $ENV{'QUERY_STRING'}; }

【ENV】とは
Perlプログラムの環境変数は、ENVという連想配列に格納されています。
通常%ENVですが、個々の環境変数を表すときには、$ENV{環境変数名}となります。
【REQUEST_METHOD】とは
環境変数の一つで、フォーム送信時に設定されるデータの受け渡し方法。POSTやGETなど。
【STDIN】とは
ファイルハンドルの一つで、グローバル変数として定義されている標準入力
【CONTENT_LENGTH】とは
環境変数の一つで、標準入力(STDIN)に格納されたPOSTによる入力データのバイト数。
【read(A,B,C)】
関数の一つ。
[A]のファイルハンドルから[B]の変数に[C]のバイト数分のデータを読み込む。
【QUERY_STRING】とは、
環境変数の一つ。「http://サーバー名/CGIスクリプト名?データ」というURLを要求した場合のデータ部分。

つまり、もし、フォーム送信時に設定されるデータの受け渡し方法がPOSTだったら
文字数をチェックしてから$bufferにフォーム送信データを書き込む。
GETだったら全文書き込む。ということらしい。

以降

@pairs = split(/&/,$buffer);

$bufferを「&」で分割して@pairsに配列として代入する。

foreach $pair (@pairs) {
  ($name,$value) = split(/=/, $pair);
  $value =~ tr/+/ /;
  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  &jcode'convert(*value,'euc');
  &jcode'h2z_euc(*value);
  $value =~ s/&/&/g;
  $value =~ s/\"/"/g;
  $value =~ s/</&lt;/g;
  $value =~ s/>/&gt;/g;
  $value =~ s/\t//g;
  $value =~ s/\,//g;
  $FORM{$name} = $value;
}

1行目~2行目
@pairsに入っている配列の数だけ同じ処理をさせ、
「=」でつながれている各項目を$nameと$valueで分ける。
3行目及び7~最終行
「&」「”」「<」「>」等の特殊文字を置き換える。
3行目で【tr】を使っている理由は正規表現逃れ、
【\t】はタブ。それ以外の\はエスケープシーケンス
最後の行で$nameと対になっているハッシュ%FORMの一つ
$FORM{$name}に変換の終えた$valueを代入。

で、分からないのは4行目~6行目。

$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

修飾子【e】をつけることで
置き換え文字列部分[pack(“C”, hex($1))]を式とみなし実行する。
【pack()】とは
リスト値[hex($1)]をバイナリ構造体に変換する関数。
[“C”]が型指定文字列といってこの場合符号なしのchar型となる。???
型とはデータ型といい。コンピュータにおけるデータの扱いに関する形式のことだそうだ。
【hex()】とは
16進数を10進数に変換する関数。
【$1】とは
正規表現内で使える特殊変数。
最後に一致した正規表現内のn番目(この場合1番目)に記憶されたグループの内容とマッチ。
これを順を追って考えてみると、
1. 最初にヒットした[% + 2桁の16進コード]が[hex()]で10進数に変換される。
2. さらにそれが[pack()]によって符号なしのchar型のバイナリ構造体に変換される
3. 符号なしのchar型のバイナリ構造体というのはすなわちテキスト
という流れになるのですが間違っていないかな?
ここ、良く分かりませんやっぱり。。
%+16進コードを捜して、そのバイナリデータを文字に変換しているのは間違いないのですが。。

途中までやってこんな素敵なサイトを見つけてしまいました。
URLエンコード・デコードのお話

で、最後の難関jcodeです。
これは、事前に[jcode.pl]を[use]か[require]で読み込ませないとダメです。
それくらいは僕でも分かります。

&jcode'convert(*value,'euc');
&jcode'h2z_euc(*value);

上記はperl4での表記方法のようです。ちなみにperl5で書くと

&jcode::convert(\$value,'euc');
&jcode::h2z_euc(\$value);

[jcode.pl]側で[package jcode]としているので、
通常の関数呼び出し表記ではなく「’」や「::」が入るようです。

で、内容は
1行目で文字コードの分からない[$value]をeucに変換。
2行目で半角カタカナを全角カタカナに変換しています。
こちらは意外と簡単でした。

下記サイトを参考にさせていただきました。
ありがとうございました。
jcode.pl の私的な解説書

ふう、やっと終わったかな。不完全だけど。。

■12月12日追記(pack関数に関して)
pack関数に関してわかりやすい資料を見つけたのでリンクしておきます。
バイナリ構造体とは – 燈明日記

 - プログラミング, 覚え書き

アドセンス広告メイン

Message

メールアドレスが公開されることはありません。

  関連記事

no image
ネットオークションを上手に活用するためのヒント

1年以上前の記事です。内容が古い可能性があります。実際ネットオークションをやって …

LINE(ライン)で友だちに友だちを紹介する方法

1年以上前の記事です。内容が古い可能性があります。これは盲点でした。 ってか、今 …

アドセンス(adsense)換金への道 前編

1年以上前の記事です。内容が古い可能性があります。初めて約1年。アドセンスから小 …

アドセンスの振込先をシティバンクのeセービングにする方法

1年以上前の記事です。内容が古い可能性があります。アドセンスの振込先をシティバン …

JPEG画像は新規保存するたびに劣化する(わけじゃない)

1年以上前の記事です。内容が古い可能性があります。JPEGってのはファイル形式で …

GIMP2で正確な切り抜き(トリミング)を速くする方法

1年以上前の記事です。内容が古い可能性があります。以前、「GIMP2は正確な切り …

no image
ワード(Word)の隠し文字の使い方

1年以上前の記事です。内容が古い可能性があります。パソコン教室でワード(Word …

書けば書くほど人がくるの法則

1年以上前の記事です。内容が古い可能性があります。「後藤真希が硫化水素自殺は本当 …

WordPress(ワードプレス)に「パンくずリスト」を付けてみた #wp

1年以上前の記事です。内容が古い可能性があります。ここのところ立て続けにWord …

デマを広める前に右クリックで「この画像を検索」。ツイッターでのリツイートは特に注意!

1年以上前の記事です。内容が古い可能性があります。先日、都内で凄い雹が降ったとツ …

血液型オヤジ