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

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

  関連記事

小さい子でもできる百人一首「坊主めくり」には様々なルールがあった

1年以上前の記事です。内容が古い可能性があります。お正月と言うことで家族で百人一 …

twitterfeedが調子悪いかも

1年以上前の記事です。内容が古い可能性があります。英語の読めない僕の設定が悪いの …

「iPhone 7」でシャッター音を出さずに写真を撮る(消音撮影する)方法【AssistiveTouch】

1年以上前の記事です。内容が古い可能性があります。「iPhone 7」といえば、 …

「OpenOffice(オープンオフィス)」の罠。画像が全て消えてしまった

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

CPUの差し替え(Pentium IIIからPentium 4へ)

1年以上前の記事です。内容が古い可能性があります。前々から調子の悪いPentiu …

ブログ(WordPress)とgoogle+の連携ができなくなっていたらチェックすること

1年以上前の記事です。内容が古い可能性があります。ブログ(WordPress)と …

no image
ライブドアブログ新「記事を書く」βver.の特徴

1年以上前の記事です。内容が古い可能性があります。ライブドアブログの「記事を書く …

ネットとテレビは仲良くなったの?YouTubeが日本で大活躍

1年以上前の記事です。内容が古い可能性があります。以下の様なまとめがNAVERま …

失業中は働いちゃダメ(ブログもダメ)、仕事を探すことに専念しよう

1年以上前の記事です。内容が古い可能性があります。そろそろ溜まったネタを小出しに …

テキストが選択できないPDFファイルからテキストを抽出する方法

1年以上前の記事です。内容が古い可能性があります。時々、PDFファイルを渡されて …

血液型オヤジ