• ベストアンサー

formデータのデコード「s///」や「tr///」

掲示板CGIの自筆に挑戦中の初心者です。form から受取った データを デコードするところで、教本やサンプルに必ず出てくる↓これですが、 $value =~ tr/+/ /; $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg; サンプル毎の微妙な違いの意味が消化できず、混乱しています。 (上記引例は杜甫々さんのサイトから拝借しました) <input type="text">に書いた「+」も1行目で半角sapceになるようですが、 (1)「+」は「+」として残すにはどうするのでしょう? (2)1行目と2行目の順番が逆だと、何か結果が変わりますか? htmlタグ不可の処理が良くわからなくて、とりあえず「=~ tr/<>/ /;」 で消しているのですが、<input type="text">に書かれた「<」や「>」を (3)「<」「>」としてhtmlに書き出すには、どうするのですか? tr/xx/yy/zz; とか s/xx/yy/zz; の「zz」が良くわかりません。 (4)引例の eg は、yyを実行文と解釈 (e)、かつ何度でも置換 (g) ですか? ついでに恐縮ですが、#によるコメント化について、 (5)$color="#rrggbb"; とか $target="#ancName"; を書いても大丈夫ですか?

  • Perl
  • 回答数3
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • 2nd
  • ベストアンサー率30% (19/63)
回答No.2

では私は (1) と (2) を。 (1) 上記のスクリプトのままで、「+」は「+」として残ります。 なぜなら、上記 $value =~ tr/+/ /; の個所の $value には URLエンコードされた文字列が入っていますので、「+」は「%2B」と あらわされており、「 」(スペース)が「+」とあらわされています。 なので、「+」を「 」に戻してやっているわけです。 (2) (1) の理由で、順番が逆だと、「+」が全て「 」に変換されてしまいます。 と、こんなところかと。

loveobo
質問者

お礼

> URLエンコード・・・「+」は「%2B」・・・「 」(スペース)が「+」// ブラウザのアドレスバー(Google検索とか)で見なれた%xx%yyの印象から、 英数字はエンコードされていないと思い込んでました。目から鱗です。 <form>に入力した「+」も「 」になってしまう手元の雛形は、tr/+/ /; が %xx%yyデコードの後に書いてありました。順番を入れ替えて解決しました。 ご回答を拝見したとき、『<textarea>から送られる改行で、それを格納した したtext file からの読み出し($\ = "\n")が撹乱』に悩んでいたのですが、 s/\n/<br>/g; に気づくキッカケとなりました。ありがとうございました。

その他の回答 (2)

  • yaya999
  • ベストアンサー率50% (4/8)
回答No.3

私も分かる範囲内で。 $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg POSTされたsjisの文字列は、URLエンコードされ、%u3042 という風になりますよね。それをCGIでデーコドする処理です。Pack関数や、hex関数はPerlリファレンス等に載っていますので、それをよく読めば処理の意味が分かると思います。 %u3042%u3044 ・・・という風に$valueに入った文字列を、hexで10進数に直し、『pack("C"』でchr型の文字へ変換している訳です。で、『/eg』は、おっしゃるとおり、pack("C",hex($1)を式と見なして、『%○○』といったパターンの文字列全てに対してpack("C",hex($1)の処理を行う、といった意味になるわけです。 また、 >htmlタグ不可の処理が良くわからなくて、とりあえず「=~ tr/<>/ /;」 >で消しているのですが、<input type="text">に書かれた「<」や「>」を >(3)「<」「>」としてhtmlに書き出すには、どうするのですか? ですが、「=~ tr/<>/ /;」に関しては、他の方がおっしゃるとおり、これではタグは除去できません。タグを削除したいのであれば、少なくとも s/<.*?>//g は必要でしょう。 また、「<」「>」を書き出すということですが、 print "<>" で表示ではだめですか?

loveobo
質問者

お礼

> Pack関数や、hex関数はPerlリファレンス等に載っていますので、// 件の1行は「お決まり」で出てくるので、理解を先送りしていますが、 ご説明を拝見し、少し「わかった気」になりました。ありがとうございます。 > s/<.*?>//g は必要でしょう。 ・・・print "<>" で表示ではだめですか// これ↑は危ない文字は削除されますね。元質問が説明不足でしたが、html form に入力された文字を、見た目の字面を保ってブラウザに返したかったので。

  • yuizuian
  • ベストアンサー率42% (103/245)
回答No.1

私の解る範囲でよろしければ… (3) =~ tr/<>/ /; これでは<>しか変換されないのは当たり前ですね、 =~ s/</&lt;/g; =~ s/>/&gt;/g; でタグを無効に出来ます。 =~ s/"/&quot;/g; もやっておいた方が良いかと。 (4) そうですね。 他にも大文字小文字を区別しない(i)とか単一行として扱う(s)なんかがあります。 (5) 大丈夫です。 ""で囲まれている所はただの文字列として解釈されます。

loveobo
質問者

お礼

(3) $value =~ s/</&lt;/g; $=~ s/>/&gt;/g; で不等号は解決しました。 カッコなどのペア文字を置換するときは、置換する相手もペア文字にする と書いてあった参考書を、「<」単独では置換できないと誤解してました。 解決後、s/x/&xxx;/; をいくつか追加したら、ブラウザに「&lt;」のまま 出てきてビックリ。#2のご回答で記述順の意味に気づきました。後ろに s/&/&amp;/; を書いてしまったために、「&amp;lt;」になってました。 (5) 変数に入れるのが不安で、いちいちhere document に直書きしてました。 ありがとうございました。

関連するQ&A

  • tr///;はカンマを処理できないのですか?

    フォームからのよくあるデコード処理を私は以下のように書いてます。 (中略) foreach $pair(@pairs){ ($key,$value)=split(/=/,$pair); $key=~ tr/+/ /; $key=~ tr/,/_/; $key=~ s/%([\dA-Fa-f][\dA-Fa-f])/pack("C",hex($1))/eg; &jcode'convert(*key,'euc'); $value=~ tr/+/ /; $value=~ tr/,/_/; $value=~ s/%([\dA-Fa-f][\dA-Fa-f])/pack("C",hex($1))/eg; &jcode'convert(*value,'euc'); $input{$key}=$value; } ところが、フォームでカンマを入力するとtr/,/_/で置換えられるはずだとおもうのですが、カンマはカンマのまま渡ってきてるようです。 tr///;はカンマを処理できないのでしょうか? csvで書き出すとき問題があると思うのです。 ご存知の方いらっしゃいましたらよろしくお願い致します。

    • 締切済み
    • CGI
  • デコード処理部分のプログラムについて

    デコード処理部分のプログラムで分からないトコがあるので教えてください。 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*value,'euc'); この『pack("C", hex($1))』、『eg』の部分の意味がよく分かりません。 『&jcode'convert(*value,'euc');』の部分も微妙なので、お願いします。

    • ベストアンサー
    • Perl
  • 半角カナを検出したい

    フォーム入力の半角カナを検出または全角に変換したいです。 ここで同じような質問をいくつかみて、いろいろ試しましたが どうもうまくいきません。 jcode.pl,v 2.6です。 デコード部分は以下のようになってます。 #!/usr/bin/perl require 'jcode.pl'; print "Content-type: text/html\n\n"; $request_method=$ENV{'REQUEST_METHOD'}; if($request_method eq "POST"){ read(STDIN,$query_string,$ENV{'CONTENT_LENGTH'}); }else{ $query_string=$ENV{'QUERY_STRING'}; } @pairs=split(/&/,$query_string); foreach $pair(@pairs){ ($key,$value)=split(/=/,$pair); $key=~ tr/+/ /; $key=~ s/%([\dA-Fa-f][\dA-Fa-f])/pack("C",hex($1))/eg; &jcode'convert(*key,'sjis'); $key=~ tr/,/_/; $value=~ tr/+/ /; $value=~ s/%([\dA-Fa-f][\dA-Fa-f])/pack("C",hex($1))/eg; &jcode'convert(*value,'sjis'); $value=~ tr/,/_/; $input{$key}=$value; } よろしくお願いします。

    • ベストアンサー
    • Perl
  • デコード処理について

    sub decode { if ($ENV{'REQUEST_METHOD'} eq "POST") { if ($ENV{'CONTENT_LENGTH'} > 51200) { &error("投稿量が大きすぎます"); } read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $in{$name} = $value; } while (($k,$v) = each %in) { $v =~ s/&/&amp;/g; $v =~ s/</&lt;/g; $v =~ s/>/&gt;/g; $v =~ s/"/&quot;/g; $in{$k} = $v; } } 上記の処理が、具体的にどうなっているのかよくわかりません。 どなたか分かる方、説明をお願いします。

  • フォームデコード

    よく見かける $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg; というやつの pack("C", hex($1)) を chr($1) にした方がいい と思ったんだけど、chr($1) のソースは見たことがないです。 chr($1) にするとうまくいかない場合があったりするんですか?

    • ベストアンサー
    • CGI
  • UTF-8から送信されたデータを日本語化するには?

    %E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A これを あいうえお に変換するには、どのようにデコードすればいいのでしょうか? ご教授お願いします。m(_ _)m [現在のソース] $buffer = $ENV{'QUERY_STRING'}; @pairs = split(/&/,$buffer); foreach $pair (@pairs){ ($name, $value) = split(/=/, $pair); $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; my $value = Jcode::convert($value, 'utf8'); $FORM{$name} = $value; } ↓ 「縺ゅ>縺・∴縺・」が検出されます。

    • ベストアンサー
    • Perl
  • ACCESS もしくはEXCEL条件によってコピー

    ACCESSもしくはEXCELで 口数の数量と同じようにそのデータ(行)をコピーしたいですが、お願い致します。 例: 住所   名前   口数 東京   XX XX  2 千葉   YY YY  1 神奈川  ZZ ZZ  3 を下の表ようにしたいです。 住所   名前   口数 東京   XX XX  1 東京   XX XX  1 千葉   YY YY  1 神奈川  ZZ ZZ  1 神奈川  ZZ ZZ  1 神奈川  ZZ ZZ  1 口数と同じようにその行を全部コピーしたですが、 宜しくお願い致します。

  • デコードできない時があります><

    なぜか「ひらがな」を偶数個送るとデコードしません 例 「あ」→「あ」 「ああ」→「縺ゅ≠」 「ああい」→「ああい」 「ああいい」→「縺ゅ≠縺・>」 「ああ質問」→「ああ質問」 「ああアあ」→「ああアあ」 今の所漢字やカナを含めて偶数個では問題無いです。 use lib './lib'; use Jcode; read(STDIN, $POST, $ENV{'CONTENT_LENGTH'}); @_post = split (/&/,$POST); foreach $tmp (@_post) { ($name,$value) = split (/=/,$tmp); $value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; Jcode::convert($value,"sjis"); $box{$name} = $value; } デコード処理はこんな感じです。 JcodeはJcode-2.07を使ってます。 独自で色々調べたのですが解決策が見つからず大変困っております。 宜しくお願いします。

    • 締切済み
    • CGI
  • form要素とtable要素

    元はこちらです。 http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1483846324 <table> <tr><td><input form="form1" type="text" value="text1"></td></tr> <tr><td><input form="form1" type="submit" value="submit1"></td></tr> <tr><td><input form="form2" type="text" value="text2"></td></tr> <tr><td><input form="form2" type="submit" value="submit2"></td></tr> </table> <form id="form1" action="cgi1.cgi" method="POST"></form> <form id="form2" action="cgi2.cgi" method="POST"></form> 上記はHTML5の仕様に従って書いていますが、これを、HTML4.01の仕様に反さないように書くと、どの様にすればいいのでしょうか。 添付画像は、実際のテーブルの様子です。

    • ベストアンサー
    • HTML
  • formのtextフィールドが認識されない

    下記のようなフォームに対し、JavaScriptで処理を行おうとしています。 <form name="dateForm" method="post" action=""> <table> <tr><td>0</td> <td><input type='text' name='date[]' maxlength='8' size=12 value='20111001'></td> <td><input type='text' name='date2[]' maxlength='8' size=12 value=''></td></tr> <tr><td>1</td> <td><input type='text' name='date[]' maxlength='8' size=12 value='20111002'></td> <td><input type='text' name='date2[]' maxlength='8' size=12 value=''></td></tr> <tr><td>2</td> <td><input type='text' name='date[]' maxlength='8' size=12 value='20111003'></td> <td><input type='text' name='date2[]' maxlength='8' size=12 value=''></td></tr> </table> <input type='text' name='date_0' maxlength='8' size=12 value='20111000'><br><br> <input type="submit" name="button" value="Check" onClick="send_self();"> <input type="submit" name="button" value="Enter" onClick="set_action();"> </form> Checkボタン押下で上記の関数を呼び出し、テキストフィールドdate[0]の値を表示すると、(1)では「20111001」と正しい値が表示されますが、(2)では下記のエラーが出てしまいます。 「プロパティ '0' の値を取得できません: オブジェクトは Null または未定義です。」 また、 alert(document.dateForm.elements[0]); // … (3) alert(document.dateForm.date); // … (4) とすると、(3)では[object]、(4)では[undefined]と表示されます。 alert(document.dateForm.date_0.value); はvalueも正しく表示されobjectとしても正しく認識されるので、配列へのアクセスに問題があるように思うのですが…。 問題点と解決法をご存知の方がいらっしゃいましたら、どうぞよろしくお願い致します。m(_ _;)m

専門家に質問してみよう