- ベストアンサー
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"; を書いても大丈夫ですか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
では私は (1) と (2) を。 (1) 上記のスクリプトのままで、「+」は「+」として残ります。 なぜなら、上記 $value =~ tr/+/ /; の個所の $value には URLエンコードされた文字列が入っていますので、「+」は「%2B」と あらわされており、「 」(スペース)が「+」とあらわされています。 なので、「+」を「 」に戻してやっているわけです。 (2) (1) の理由で、順番が逆だと、「+」が全て「 」に変換されてしまいます。 と、こんなところかと。
その他の回答 (2)
- yaya999
- ベストアンサー率50% (4/8)
私も分かる範囲内で。 $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 "<>" で表示ではだめですか?
お礼
> Pack関数や、hex関数はPerlリファレンス等に載っていますので、// 件の1行は「お決まり」で出てくるので、理解を先送りしていますが、 ご説明を拝見し、少し「わかった気」になりました。ありがとうございます。 > s/<.*?>//g は必要でしょう。 ・・・print "<>" で表示ではだめですか// これ↑は危ない文字は削除されますね。元質問が説明不足でしたが、html form に入力された文字を、見た目の字面を保ってブラウザに返したかったので。
- yuizuian
- ベストアンサー率42% (103/245)
私の解る範囲でよろしければ… (3) =~ tr/<>/ /; これでは<>しか変換されないのは当たり前ですね、 =~ s/</</g; =~ s/>/>/g; でタグを無効に出来ます。 =~ s/"/"/g; もやっておいた方が良いかと。 (4) そうですね。 他にも大文字小文字を区別しない(i)とか単一行として扱う(s)なんかがあります。 (5) 大丈夫です。 ""で囲まれている所はただの文字列として解釈されます。
お礼
(3) $value =~ s/</</g; $=~ s/>/>/g; で不等号は解決しました。 カッコなどのペア文字を置換するときは、置換する相手もペア文字にする と書いてあった参考書を、「<」単独では置換できないと誤解してました。 解決後、s/x/&xxx;/; をいくつか追加したら、ブラウザに「<」のまま 出てきてビックリ。#2のご回答で記述順の意味に気づきました。後ろに s/&/&/; を書いてしまったために、「&lt;」になってました。 (5) 変数に入れるのが不安で、いちいちhere document に直書きしてました。 ありがとうございました。
お礼
> URLエンコード・・・「+」は「%2B」・・・「 」(スペース)が「+」// ブラウザのアドレスバー(Google検索とか)で見なれた%xx%yyの印象から、 英数字はエンコードされていないと思い込んでました。目から鱗です。 <form>に入力した「+」も「 」になってしまう手元の雛形は、tr/+/ /; が %xx%yyデコードの後に書いてありました。順番を入れ替えて解決しました。 ご回答を拝見したとき、『<textarea>から送られる改行で、それを格納した したtext file からの読み出し($\ = "\n")が撹乱』に悩んでいたのですが、 s/\n/<br>/g; に気づくキッカケとなりました。ありがとうございました。