68user's page 掲示板

Prev< No. 2205〜2210> Next  [最新発言に戻る] [過去ログ一覧]
No. 2205 # ナナシサソ 2001/10/13 (土) 20:40:22
>>2204 shii
http://www.din.or.jp/~ohzaki/perl.htm#JP_Code

っていうかそのコードには
気になる点がいろいろと・・・

No. 2206 # shii 2001/10/13 (土) 21:24:57
>>2205 ナナシサソ
リンク先はPerlメモのgetcode関数のところですね。
できれば気になる点を具体的に指摘していただけると
とてもありがたいのですが。

No. 2207 # 68user 2001/10/13 (土) 21:45:30
>>2204 shii
考え方はよいのですが、もちっとスマートにやるなら、
    「あ」の文字コードを調べるスクリプト
        require 'jcode.pl';
        $_="あ";
        jcode::convert(\$_, 'euc');
        s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
        print "あ in euc-jp: $_\n";
        $_="あ";
        jcode::convert(\$_, 'sjis');
        s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
        print "あ in shift_jis: $_\n";
        $_="あ";
        jcode::convert(\$_, 'jis');
        s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
        print "あ in jis: $_\n";

    実行結果:
        あ in euc-jp: %A4%A2
        あ in shift_jis: %82%A0
        あ in jis: %1B%24B%24%22%1B%28B # これは他のパターンも有りうるかも
を踏まえて、
    <input type="hidden" name="assist" value="あ">
としておき、
      read(STDIN,$input,$ENV{'CONTENT_LENGTH'});
      
      ($assist_code) = $input =~ s/(^|&)assist=(.*?))($|&)//;

      if ( $assist_code =~ m/^\%A4\%A2$/i ){
          $input_encoding = 'euc';
      } elsif ( $assist_code =~ m/^\%82\%A0$/i ){
          $input_encoding = 'sjis';
      } elsif ( $assist_code =~ m/^\%1B\%24B\%24\%22\%1B\%28B$/i ){
          $input_encoding = 'jis';
      }

      @parts = split(/&/,$input);
      foreach(@parts) {
              ($key,$val) = split(/=/);
              $key =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;
              $val =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;
              jcode::convert(\$key,'euc', $input_encoding);
              jcode::convert(\$val,'euc', $input_encoding);
      }
くらいがよろしいかと思います (動作確認はしていません)。

>>2203 AGE
> ntp はソースから make install しました。
> その場合のインストールされたファイルを知りたかったのです。
もし Makefile に uninstall とか deinstall とかいうターゲットがあるなら、
    # make uninstall
    # make deinstall
ですが、なさそうならば
    # make -n install
して、インストールされるファイルをメモって、手動で rm ですね。

>>2202 スナフキン
> ServletもCGIと同じくリクエスト毎に起動するのですか?
いいえ、しません。そういう意味では常駐していますね。

しかし、CGI を使うときも apache が常駐していますが、「常駐
システムを開発している」という意識は僕にはありません。それと
同様に、Servlet コンテナが常駐していても「常駐システム」とは
呼ばないんじゃないなぁ、ということです。まぁ、ここらへんの
感覚は人によって違うのかもしれません。

>>2200 /tk
> どちらもスライスだと思うのですが
えっと、@a[0] と (@a)[0] は違うんですよね? ということです。

要は、
    「@a[0] は文法エラーのところを perl があえて $a[0] に読み変えている」
とこれまで思っていたのですが、
    「@a[0] は文法的には正しいけれど、$a[0] の方が適当なので
        perl があえて警告するようにしている」
ということでしょうか?

> @a は配列のスライスで, (@a) はリストのスライスかと…
perl に配列とリストという区別はあるんでしたっけ。

No. 2208 # shii 2001/10/14 (日) 09:24:30
>>2207 68user
おお,なるほど!ありがとうございます。
ダミーを送るのなら,それをわざわざ対象文字列に結合しなくても
いいわけですね。私が間抜けでした。

文字コードを調べるスクリプトが面白いですね(勉強になります)。

今回の件を自分のCGI向けに最小限にカスタマイズした(つもりの)
スクリプトが下記です。

#---------------------------------------------------------
read(STDIN,$input,$ENV{'CONTENT_LENGTH'});
@parts = split(/&/,$input);
foreach(@parts) {
    ($key,$val) = split(/=/);
    $val =~ tr/+/ /;
    $key =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;
    $val =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;
    
    $code = &jcode::getcode(\$key);
    jcode::convert(\$key,'euc',$code);
    jcode::convert(\$val,'euc',$code,"z");
    
    $val =~ s/\r\n|\r|\n//g;
    $val =~ s/,/,/g;
    $in{$key} = $val;
}
#---------------------------------------------------------

入力項目名に半角カナ以外の日本語を使用することが前提なので,
汎用性はありません。
getcode関数を全項目に使っているところが余分なのですが,
見た目は,以前に比べてすっきりしました。

ところで,
> ($assist_code) = $input =~ s/(^|&)assist=(.*?))($|&)//;
ここはassistの中身のみを残して残りを消す作業だと思うのですが,
($assist_code)にカッコがついている理由と,
正規表現内のカッコの数が合わない理由を教えてください。

・「行の先頭」または「&の直後」にある「assist=」
・「任意の1文字の0回以上の最短マッチ」
・「行の終わり」または「&の直前」

と,部分的にしか理解できませんでした。

No. 2209 # ナナシサソ 2001/10/14 (日) 18:02:18
>>2208 shii
おいらはこう書くべきと思うけどな
my ($assist_code) = $input =~ /(?:^|&)assist=([^&]*)/;
どうせassist=なんじゃら、なんて残ってたって関係ないし。

> 正規表現内のカッコの数が合わない理由を教えてください。
ミスだねこれは

だいたい、これだと
> ($assist_code) = $input =~ s/(^|&)assist=(.*?))($|&)//;
$assist_codeに入るのは(^|&)の部分になっちゃう

No. 2210 # AGE 2001/10/15 (月) 12:29:41
>2207 68user

>もし Makefile に uninstall とか deinstall とかいうターゲットがあるなら、
> # make uninstall

これでうまくいきました。ありがとうございました。

Prev< No. 2205〜2210> Next  [最新発言に戻る] [過去ログ一覧]