新・元地方の中規模印刷会社で苦悩する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
iframeの高さを内容に合わせて変えるスクリプト

1年以上前の記事です。内容が古い可能性があります。非推奨ながらもなかなかなくなら …

WordPress(ワードプレス)を会員制のサイトにする方法1 #wp

1年以上前の記事です。内容が古い可能性があります。ここではサイト全体を会員制にし …

他サービスとの連携を止める方法 【foursquare編】最新版

1年以上前の記事です。内容が古い可能性があります。foursquare(フォース …

「Taberareloo」がよさそうなのでFirefoxからChromeに乗り換えた【前編】

1年以上前の記事です。内容が古い可能性があります。「Taberareloo」って …

「use strict」に対応させる簡単な改造方法【perl】

1年以上前の記事です。内容が古い可能性があります。色々なところでperlのプログ …

Flickr(フリッカー)でALBUMS(アルバム)のスライドショーの埋込みソースを入手する方法

1年以上前の記事です。内容が古い可能性があります。写真共有サイトのFlickr( …

普通郵便よりちょっと安いが「ゆうメール」は封筒では送れない

1年以上前の記事です。内容が古い可能性があります。あまり使ったことないとどうして …

Flicksquareの設定を復活させる方法(foursquare→Flickr連携)

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

ブラインドタッチを覚えるための10のポイント

1年以上前の記事です。内容が古い可能性があります。先日より、ブラインドタッチを覚 …

さくらインターネットとWordPressで不動産サイトを作った

1年以上前の記事です。内容が古い可能性があります。WordPressに不動産プラ …

血液型オヤジ