• ベストアンサー

&(半角アンド)が含まれる文字列の分割

http://oshiete1.goo.ne.jp/kotaeru.php3?q=644082 質問したものです。 &が%26なのはわかったのですが、それを分割する術がわかりません。 ただ普通にsplitでやってしまうと意図しない&で切れてしまいます。 どのようにしたらいいですか?

  • Perl
  • 回答数6
  • ありがとう数5

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

  • ベストアンサー
  • Ethersky
  • ベストアンサー率71% (168/235)
回答No.2

URLデコード前に&を使って分けましょう。 そして連想配列(ハッシュ)に突っ込みましょう。 で、煮るなり焼くなりした方がいいです。(というかそれが普通です) 見たところ、遠回りなことやってますよ。 read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); foreach $pair (split(/&/,$buffer)){ ($name,$value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$name} = $value; } それと、配列なのに > @filew = "$TITLETITLE=$TITLE&$DATETITLE=$DATE&……\n"; とやっている意味が不明です。 これなら普通に変数に代入するべき。 で、使いまわさないなら print FH "$TITLETITLE=$TITLE&$DATETITLE=$DATE&……\n"; とやった方がメモリを無駄に消費せずに済みます。 最後に、日本語が混ざったりするならjcode.plなりJcode.pmに通した方が身のためですよ。(ぉ)

KODAMAR
質問者

お礼

回答ありがとうございます。 read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); $buffer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; foreach $pair (split(/&/,$buffer)){ ($name,$value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$name} = $value; } この方法は使ってました。 というかこれでやろうと思ったのですができなくて、今みたいな方法をとってみたんですが(苦し紛れに) 上記の方法でやると、 $NAKAMI =~ /^(.*?)=(.*)$/;$NAKAMITITLE = $1;$NAKAMI = $2; のやり方がわからないんです。 こういうことをやるためにはどうしたらいいのですか? foreachの中に $FORM{$name} =~ /^(.*?)=(.*)$/;$name = $1;$value = $2; とやってみましたがダメでした。

その他の回答 (5)

  • estea
  • ベストアンサー率44% (39/87)
回答No.6

require '../jcode.pl'; read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); foreach $pair (split(/&/,$buffer)){ ($name,$value) = split(/=/, $pair,2); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$name} = $value; } でかまいません。 jcode をrequire しているのに処理が書かれていませんが :P >この方法は間違っているでしょうか? 動いているなら問題ありません(ぉ ただ、form から送られる場合、普通 split の第三引数は必要ありません。 なぜなら formデータ中の = は %xx 形式のままだからです。だからこそsplit 下後の、代入直前で $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; を行って = に戻しています。同様に & もここで戻されます。 split 第三引数が持ち出された理由は split するより前に $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; していたことか、 $bugffer='a=b&c=d=e' のような代入をスクリプト内で行っていたためです。 ただし、以上は form からの入力の場合です。アンカーなどで自分で引数を組み立てた場合はURLエンコードのタイミングがブラウザのそれとずれるかもしれませんので、それぞれに考える必要はあります。

KODAMAR
質問者

お礼

すいません、無事できました。 こちらの勘違いでした。

KODAMAR
質問者

補足

回答ありがとうございます。 なんとか無事できそうです…と思っていたらまた問題発生です…。 ---------------------------------------- ふつう  41~60 少し悪い 21~40 最悪    1~20 とメッセージを出すプログラムを書いてみたいと思います。 If n = 2 Then MsgBox "チョキを出しました" End If と単独の条件は、やりましたね。 If文では、And 演算子 Or 演算子 を使用して、複数の条件を書くことが出来ます。 簡単に書くと、 If 評価する男性 = 金持ち And 評価する男性 = カッコイイ then と書くと、男性が金持ちで なおかつ 男性がカッコイイ両方の条件を満たす時、 If 給料 = 高い Or 場所 = 近い then と書くと、給料が高い か 場所が近い時 どちらかの条件がOKの時です。 ふざけてないで、真面目に解説しろ?って、 話を戻して、 1から100の乱数を発生させ、今日の運勢 最高   81~100 と表示なので、 数値が81より大きく、100より小さい時なので、 If 乱数 >= 81 And 乱数 <= 100 then If n >= 81 And n <= 100 then となります。 ---------------------------------------- という文章を打っていたとします。 (とあるメルマガからの抜粋です。) すると上記の例の下から3行目の「If 乱数 」までで切れて、 「= 81 And 乱数 <=~」から下が表示されてしまいます。 入力は正常に行えています。別のフォームから見たときは表示もきちんとされています。 ただ、searchという形をとった時のみ、切れてしまいます。 どこが原因なのでしょうか?

回答No.5

蛇足かもしれませんがいくつかアドバイスを。 ログファイルにデータが出なかった理由ですが、 $ENV{'CONTENT_LENGTH'} が小文字になっているからです。 (Perlは変数名の大文字と小文字を別物として扱うため) あとはログの方にもデータが現れると思いますが、 途中で経過を出力するなりして受け渡しを研究してみてください。 一点気をつけることとしては、 ($TITLE,$DATE,$NAKAMI,$WORD,$TIME,$SEARCHKEY)=split(/&/,$buffer,6); の部分ですが、 受け取ったデータが必ずしも title, date, nakami word … の順に並んでるとは限りません。 IEではformタグの順番通りに来るようですが、 それでもaction=postが先頭に来ると思います (正式な規格などは存じ上げませんが) 結論としては、どんな順序で受け取ってもかまわないように 受け取る側でプログラムしておくのが大事かと思います。 (それもあってハッシュを通常使います。  もちろん、効率の面もありますが)

KODAMAR
質問者

お礼

回答ありがとうございます。 >$ENV{'CONTENT_LENGTH'} >が小文字になっているからです。 しりませんでした。気をつけます。 >受け取ったデータが必ずしも >title, date, nakami word … >の順に並んでるとは限りません。 >IEではformタグの順番通りに来るようですが、 >それでもaction=postが先頭に来ると思います 是も知りませんでした。 例えば相手のブラウザがIEではない場合、意図しない動きをするってことですよね? ありがとうございました

KODAMAR
質問者

補足

ここに書かせていただきますが、 =の件については無事解決しました。 read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); $buffer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; foreach $pair (split(/&/,$buffer)){ ($name,$value) = split(/=/, $pair,2); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$name} = $value; と、splitの部分で「2」と指定してやることでのりきれました。 やはり&が残ってしまいました。。。 どのようにしたらいいのでしょうか?

  • estea
  • ベストアンサー率44% (39/87)
回答No.4

ごめん。 偉そうに言って間違ってる。 name の + もスペースに戻すべきかもしれんし jcode.pl も第一引数は \$value のほうがよさそう 文字コードは euc のほうがよさそうだし

KODAMAR
質問者

補足

すいません、かくところがなくて、ここに書かせていただきます。 #5の回答の補足よりもこちらの方が最新です。 ~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; として、=や&を最初に文字にしてしまうから分割されるんであって、最初に分割してから文字にすれば…という考えにいきつきまして…。 それで以下のように変更してみました。 require '../jcode.pl'; read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); #$buffer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; foreach $pair (split(/&/,$buffer)){ ($name,$value) = split(/=/, $pair,2); $value =~ tr/+/ /; #$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$name} = $value; $FORM{$name} =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; } 一応表示は無事できました。 この方法は間違っているでしょうか? 私はまた何か危ないことをやらかそうとしてるのでしょうか?(^^; もしこれで何か今後不都合が予想されるなどありましたら教えてください。

  • estea
  • ベストアンサー率44% (39/87)
回答No.3

えっと、前の 「=でうまく切れない」 でお尋ねの splitの 第三引数ですが、ココで指定された引数個以上に分割しないってことです。 $buf = 'a=b=c=d'; のとき split(/=/,$buf,2) すれば返る配列は ('a' , 'b=c=d') です。 GETやPOSTを受け取る方法は、流儀はあるとは思いますが結構普通に使われているコードは、以下のようなのだと思います。 #reqire 'jcode.pl'; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } foreach $pair (split(/&/,$buffer)) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; #&jcode'convert(*value,'sjis'); #日本語使うなら。 $FORM->{$name} = $value; } 他にこういった部分では、タグの無効化とかファイルの保存書式上邪魔な文字の置換とかいろいろやるんだと思います。

KODAMAR
質問者

お礼

回答ありがとうございます。 >$buf = 'a=b=c=d'; のとき >split(/=/,$buf,2) すれば返る配列は >('a' , 'b=c=d') です。 やっぱりそうなんですね!! 例えば$bufferが3つの構成からなっていて、その2つ目のところに=や&が入ることがある場合、 3と指定してしまうと、2つ目のところの途中で終ってしまうんですよね?

KODAMAR
質問者

補足

すいません、間違ったのを書いたのを送信してしまいました。 $buffer = A=4&B=4=5=6&C=1 だった場合、3を指定したら A=4,B=4,5=6C=1 となってしまうんですよね? A=4,B=4=5=6,C=1 としたいのですが。。。

回答No.1

他のログの方拝見しましたが、 やはり状況が今ひとつわかりません。 >ただ普通にsplitでやってしまうと意図しない&で切れてしまいます。 splitする対象のデータに&があれば当然そこで分割されます。 ただし、普通はsplitされる時には%26になっているはずです。 (ですので、そこで分割されないことになります) もし分割したいのであれば、 splitする前に%26を&に戻しておく必要があります。 >=や&を文章中に使うと、そこで意図しなくてもわかれてしまいますよね? とのレスが前のログにありましたが、 なにかしら勘違いがあると思います。 一度getでデータを渡すなりして確認してみるべきでしょう。 また、 split第三引数の話も他の方のコメントにありました。 これも調べてみることをおすすめします。 #私の方で勘違いありましたらすみません。

KODAMAR
質問者

お礼

回答ありがとうございます。 今一度説明させていただきます。 フォームcgiで入力されたデータをPOSTで別cgi(2.cgi)で取得、ログファイルへ書き込みします。 ●2.cgiの例 read(STDIN,$buffer,$ENV{'content_length'}); $buffer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; ($TITLE,$DATE,$NAKAMI,$WORD,$TIME,$SEARCHKEY)=split(/&/,$buffer,6);    ←ここに「6」を足してみました。    : ($TITLETITLE,$TITLE)=split(/=/,$TITLE); ($DATETITLE,$DATE)=split(/=/,$DATE); $NAKAMI =~ /^(.*?)=(.*)$/;$NAKAMITITLE = $1;$NAKAMI = $2;    : $NAKAMI =~ s/=/%3D/g; $NAKAMI =~ s/&/%26/g;    : open(FH,">>log.log"); @filew = "$TITLETITLE=$TITLE&$DATETITLE=$DATE&……\n"; print FH @filew; close(FH); となってます。 この時点でログファイルをみても「&」のみ(というか&以降)が書き込みされていません。 この時点で&が%26と入力されるようにしたいのですが。 あまり詳しくないながら書いたコードですので、面倒臭いことやってるなーという点も多々あると思いますが、 私にはこのように1つ1つ追っていかないとわからなくなってしまうので…。

関連するQ&A

  • &(半角アンド)を扱うには?

    http://oshiete1.goo.ne.jp/kotaeru.php3?q=639906 で質問したものです。 =は無事解決したのですが、今度は&で問題が…。 =だったら%3Dと表すようですが、&はどのようにするのでしょうか? 自分なりに調べた結果 . %2E / %2F ? %3F というのはわかったのですが、これ以外がわかりません。 詳しく書いてあるページ、もしくは教えてくださる方、よろしくお願いします。

    • ベストアンサー
    • Perl
  • ""で囲まれていない箇所にある空白で分割

    PHPのカテゴリにて、 http://oshiete1.goo.ne.jp/kotaeru.php3?q=2334460 で同様の質問をした者なのですが、解決策を得られなかったので再度(こちらのPerlカテゴリにて)質問させて下さい。 (1)題名の通り、""に囲まれていない箇所にある空白によって文字列を分割したいのですが、split()等を使って一発で分割する正規表現はあるでしょうか。 (2)もし(1)が無理であれば、どういった手法が有効でしょうか。 ちなみに今のところ以下の方法で行っています。  1."" 中の空白をいったん別の文字に変換  2.split(/\s/) で分割  3.分割した各要素について1で変換した空白を復元

    • ベストアンサー
    • Perl
  • 過去一年間ぐらいの分割銘柄を見たいです

    この質問の続きなのですが http://oshiete1.goo.ne.jp/kotaeru.php3?q=2443317 あと分割発表日も知りたいです。 そこまで載ったサイトなどはないでしょうか?

  • アルバム1枚のmp3ファイルの分割について

    過去質問↓ http://oshiete1.goo.ne.jp/kotaeru.php3?q=461374 を見て、フリーソフトで単純に分割できないソフトの 拡張子を.zipに変更して「Lhasa」で解凍を試みましたが、 「未知の形式」というエラーメッセージが出ます。 どーしたらいいんでしょう。・゜・(ノД`)・゜・。  

  • 文字化け

    http://oshiete1.goo.ne.jp/kotaeru.php3?q=509056 の質問みたいに どうして文字化けは起こるのでしょうか?

  • mp3ファイルの分割について

     「音声ファイルの分割について」というタイトルで、 http://oshiete1.goo.ne.jp/kotaeru.php3?q=2167563 で質問させていただいたものです。  mp3DirectCut v2.02で、 mp3ファイルの不要部分のカットはできました。 http://www.xucker.jpn.org/pc/mp3directcut_install.html  しかし、分割(二つや三つのファイルに分ける)ができないように思われます。 できればフリーで、結合もできるものが理想です。  よろしくお願いします。

  • エレキギターの音階について3

    http://oshiete1.goo.ne.jp/kotaeru.php3?q=1792145 1 http://oshiete1.goo.ne.jp/kotaeru.php3?q=1792153 2 です。 2では「高いドより上はどうやるのですか?」と質問させていただきました。大分出来るようになったのですが、普通の『ド』より低い音はどうやるのですか? 本を買いに行きたいのですが、値段がちょっと痛かったので、買うことが出来ませんでした(汗 よろしくお願いします!!

  • 半角と全角が混ざった文字列のバイト処理に関して

    失礼します。 "あイウエお"という文字列があったとして、 出力する場所に6バイト分の幅しかない場合、 "あイウエお"だと7バイトになってしまい入らないので "あイウエ"だけ抜き出して出力し、 2行目に"お"と出力するにはどのような記述をすれば良いのでしょうか?全角の文字を途切らせないで、入りきれないなら次行に移したいのです。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=172521 に載ってるソースを参考にしてみたのですが、上手くいきませんでした。。

  • split と 正規表現による分割

    http://oshiete1.goo.ne.jp/kotaeru.php3?q=964020 にて同じような質問をしたのですが、ご回答と自分での検証で食い違いが起きたので質問させていただきます。 splitを用いた分割と正規表現を用いた分割のどちらが速いかというものです。 #####test.txt### ... <!--line--> ... <!--line--> .... ################ というファイルを$lineという変数に入れ、 ********************************************** sub seiki { my $a,$b,$c; if($line=~ /(.*)<!--line-->\n(.*)<!--line-->\n(.*)/s){ $a=$1; $b=$2; $c=$3; } ********************************************** と ********************************************** sub split { my($a,$b,$c){split("<!--line-->\n",$line);} } ********************************************** をBenchmarkモジュールを用いて、速度比較をしてみたところ、splitの方が4倍程速い結果が出ました。実際に用いたtest.txtのサイズは10KBです。 前回質問したときのご回答では、正規表現のほうが早いというご意見をいただいたのですが、本当のところはどちらなのでしょうか

    • ベストアンサー
    • Perl
  • 恋愛依存症とは???

    こんにちは!! いつもお世話になってます。。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=629254 http://oshiete1.goo.ne.jp/kotaeru.php3?q=630879 http://oshiete1.goo.ne.jp/kotaeru.php3?q=633725 http://oshiete1.goo.ne.jp/kotaeru.php3?q=644351 ↑↑↑↑↑ 今まで質問してきたものですが これを見て私は恋愛依存症だと思いますか?? 自分でもそうなのかな??と思ったりしますが どうなんでしょう?? そしてどうしたら恋愛依存症から立ち直ることが できますか?? やっぱり趣味とか見つけたり仕事に打ち込んだりするのが一番なんでしょうか?? 私は、今の彼のことで悩んでいますが、 なんとか立ち直りたいんです!! 今の自分がいやでいやで堪らないんです。。 彼だけのことを考えている自分が情けないんです。。 恋愛依存症になったことがある方、そうでなくても構いませんが何かいい方法はないでしょうか?? よろしくお願いします!!