新・元地方の中規模印刷会社で苦悩する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

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

  関連記事

Adsense(アドセンス)でフィルタリングをうまく活用しよう

1年以上前の記事です。内容が古い可能性があります。先日、「滞在時間が長いページの …

雪道を走るのに身を持って感じた注意点

1年以上前の記事です。内容が古い可能性があります。一緒に行かれた方には本当に申し …

ブログやサイトにカレンダーを簡単に置く方法

1年以上前の記事です。内容が古い可能性があります。お客さんに自分で編集できるカレ …

スマホ(スマートフォン)を機種変した時のLINE(ライン)の移行手順と注意点【Android→iPhone編】

1年以上前の記事です。内容が古い可能性があります。スマホをiPhoneに変えた旨 …

no image
ホメオパシーとは何のこと?

1年以上前の記事です。内容が古い可能性があります。ここ数日、難しめブログに「ホメ …

Flickrで「保険」と検索したらヤバい画像がたくさん出てきた

1年以上前の記事です。内容が古い可能性があります。この前の記事を書くに当たり、F …

「ヨメレバ」が便利そうなので色々なアフィリエイトに手を出してみた(7net / ブックオフ編)

1年以上前の記事です。内容が古い可能性があります。7net(セブンネットショッピ …

スマホ(スマートフォン)にブックマークレットを登録する方法

1年以上前の記事です。内容が古い可能性があります。以前、スマホで使えるブックマー …

no image
cgi(perl)にhtmlを読み込ませる方法

1年以上前の記事です。内容が古い可能性があります。たとえば与えられた変数によって …

東京ディズニーリゾートチケットはネットで購入が楽でいい【チケット購入編】

1年以上前の記事です。内容が古い可能性があります。1. ユーザー登録編&nbsp …

血液型オヤジ