• ベストアンサー

CGIでのgrep関数においての質問

Perl言語で作成するCGIプログラムについての質問なのですが、grep関数をつかって文字のマッチングを試みて、1回目はうまくいったのですが、同じように2回目を同じプログラムで使ったところ、絶対に0件マッチになります。検索対象も、検索文字列も、スカラー変数でだしてみて目で確認して明らかに合致しているのに0件になります。 ちなみに、使用した関数は以下のような感じです。 @hit = grep(/$data1/,@data2); $hit = grep(/$data1/,@data2); $hitでだしてみても0になりますし、@hitも何も入っていません。 grep関数は2回使えないのでしょうか。 検索文字はメールアドレスなのですが、前のプログラムで同じように関数を使って成功していますので、検索文字が原因ではないと思いますが。 ご回答お願い致します。

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

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

  • ベストアンサー
  • venzou
  • ベストアンサー率71% (311/435)
回答No.3

検索パターンの方をファイルから読み込んでいるのですね。 では、こちらの改行コードが問題になります。 $mailaddress = <FILE>; chomp $mailaddress; ファイルから読み込んだら、行末の改行コードも含まれますので、 不要な場合は削除して下さい。 ----------------------------------------------------------- >1. $mailaddress = "abcde@fghijk.com"; >2. $mailaddress = "abcde\@fghijk.com"; ダブルクオートで囲った文字列は変数が展開されます。 1は @fghijk の部分が変数名と誤解されてますね。 2の様にエスケープするか、シングルクオートで囲えば問題ないはずです。 $mailaddress = 'abcde@fghijk.com'; ファイルから読み込んだ場合は、変数は展開されませんので、 問題ないはずです。 また、@ は正規表現内ではエスケープ不要です。 ----------------------------------------------------------- しかし、メールアドレスに使われるピリオドは問題です。 これは正規表現では特別な意味を持ちますので、 エスケープする必要があります。 念のためピリオド以外もエスケープして、 下記のような感じでどうでしょう? $mailaddress = <FILE>; chomp $mailaddress; $mailaddress =~ s/([\$\(\)\*\+\.\?\[\\\]\^\{\|\}])/\\$1/g; @hit = grep(/$mailaddress/,@data);

coop10
質問者

お礼

chomp関数で検索文字$mailaddressの改行文字を切り落とすことで解決できました。 ご指摘通り、改行文字が邪魔になっていたようです。 ご丁寧にありがとうございました。

その他の回答 (2)

  • venzou
  • ベストアンサー率71% (311/435)
回答No.2

>grep関数は2回使えないのでしょうか。 回答出てますが、何度でも使えるはずです。 原因は他の所にあると思います。 --------------------------------------------------- $data1、@data2の具体的な内容が分からないと、 何とも言えませんが、よくある失敗は改行コードかな。 これは目で確認しても気付き難いです。 grepの前で、改行コードを消してみて下さい。 chomp @data2; --------------------------------------------------- 上記で解決しない場合・・・ >前のプログラムで同じように関数を使って成功していますので、検索文字が原因ではないと思いますが。 書いた本人には、そういう思い込みがあります・・・ 他人の目で見ると、簡単に原因が見付かる場合もありますよ。 出来れば、具体的なデータを補足して下さい・・・と、言いたい所ですが、 メールアドレスなら、生のデータは書けませんね。(^^; 架空のアドレスで、不具合の出るデータは作れませんか?

coop10
質問者

お礼

chomp関数をつかってもヒットしませんでした。 しかし、アドレスをログからファイル操作で読み込んで変数に代入していたのですが、変数を直接指定してやると、 ($mailaddressは$data1の部分で検索文字です) 1. $mailaddress = "abcde@fghijk.com"; 2. $mailaddress = "abcde\@fghijk.com"; 1だと$mailaddressは abcde.com になり、2は abcde@fghijk.com になり、2はヒットしました。 しかし、ファイル操作で読み込むため、 $mailaddress = <FILE>; となり、@をエスケープできません。 もし、ヒットしない理由が上の$mailaddressが要エスケープでヒットしないなら、エスケープする方法はあるんでしょうか?

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

> grep関数は2回使えないのでしょうか。 使えますよ。以下は検証コード: use Data::Dumper; $d = 'a'; @d = qw( abc def zax ); print "[1]\n", Dumper( grep( /$d/, @d ) ), "\n"; print "[2]\n", Dumper( grep( /$d/, @d ) ), "\n";

coop10
質問者

お礼

ご回答ありがとうございます。 Dumper関数で検証してみたのですが、やはり何も表示されませんでした。 [1] [2] というかんじで。

関連するQ&A

  • 簡易grep関数ができません。助けてください><

    はじめまして。 C言語初級者の大学生です。 このたび、大学で出た課題で、Perlで製作した簡易grep関数 プログラムを元に、C言語で同様の内容をプログラミングせよ、 という課題が出題されました。 大半はできたのですが、肝心の文字列検索アルゴリズム(特定のワードを含んだ文章の検出)がわかりません。 やり方教えてください、お願いします>< OS:Mac OS X 10.8.5 エディタ:vi Editor 【参考】 Perlで製作した簡易grep関数 #grep for perl version #usage:mygrep pattern file1,file2,... if(@ARGV<1) {die:"Usage mygrep pattern [file.]\n";} $pattern=shift foreach $file (@ARGV) { open(FILE,$file); $line=1; while(<FILE>){ #--------------------------------------------- print "$file $line:$_" if /$pattern/o; #--------------------------------------------- # ↑この部分をC言語で表したいです $line++;} close(FILE); }

  • perl上でのgrepでエラーとなる文字の対応

    perlプログラム内で、grepを行っております。 grep対象の中身に +、*、(、)、[、]などの文字列が含まれているため、エラーとなり、 プログラムがうまく動作しません。 grepしたい対象データ例:http://www.XXX.co.jp/○○+▲▲ http://www.XXX.co.jp/○○+▲▲の+を 文字として判断し、正規表現扱いではないとしたい。 http://www.XXX.co.jp/○○+▲▲を含む文字を抽出したい。 perl プログラムにおいて @line1 = grep(/$url/,<ARG>); という記述しておりますが、どのように変更すればよいでしょうか? また、grepしたい対象データがファイルに格納されておりますが、 その中で、+を \+ にファイル一括変換する場合、:%s/+/\+/g で やろうとしても、変換されません。 perlプログラムでの対応、grep元ファイルの変換処理方法 それぞれのやり方について教えてください。

    • ベストアンサー
    • Perl
  • grepの書き方がわかりません。

    Perlの初心者なんですが、以下のようなテーマをもらってプログラムを作っています。  第一引数にディレクトリのパス、第二引数に検索し たいファイル名を指定して第一引数の  パス以下にある全てのディレクトリを検索してファイルがあればそのパスを表示させなさい。 一応できたのですがプログラムの記述の一部がよくわかりません。以下のプログラムは一部です。 local ($dir, $file) = @_; opendir(DIR,$dir) or die @data = readdir(DIR);#ディレクトリの内容を読む closedir(DIR);#ディレクトリを閉じる local @fname = grep {-f "$dir/$_"} @data; local @dname = grep {-d "$dir/$_"} @data; $dir,$fileには第一、第二引数の文字列をいれているのですがそのディレクトリになかにファイル、ディレクトリがないか検索するためgrepを使っています。それで"$dir/$_"の部分の意味がよくわかりません。 この部分は他のサイトであったものを流用しただけなのですがよくわからないまま使ってたまたま動いたから使用しててこのままでは理解していないままなので どうか教えてほしいです。 あともう一点ありましてgrepのところで最初自分で書いた時  local @fname = grep (-f,@data); というように書きました。ファイルが第一引数にあるときは問題なく動作するのですがその下にあるディレクトリにあるとなぜかプログラムが終わりません。 デバッグとして@dataの中身を表示したらそのディレクトリの検索をしてはいるんですが、その中に目当てのファイルがあるはずなのに@dataの中身がからっぽで ファイルがないことになっています。この違いがどうしてもわかりません。  以上の二点がわからないんですがどうかお手数ですがどなたか教えてください。  

    • ベストアンサー
    • Perl
  • 同条件で連続grepすると2回目がHITしない

    grepを使った下記のようなプログラムの出力結果が理解できません。 --------------------------- @arr=("a"); $str="a"; @buf=grep{m/$str/g} @arr; print "buf=[@buf]\n"; @buf=grep{m/$str/g} @arr; print "buf=[@buf]\n"; --------------------------- [出力結果] buf=[a] buf=[] --------------------------- なぜ連続で同じ条件でgrepすると2回目はHITしないのでしょうか? なお、さらに繰り返しても、 buf=[a] buf=[] buf=[a] buf=[]  :  : のように一回おきにHITします。 また条件を一回ごとに変えるともちろんうまくHITします。 中で何が起きているのか理解できないので、 わかる方いらっしゃいましたら教えていただけないでしょうか? perlはActivePerl-5.8.7です。 なお、実際当方のプログラム内ではループの中で$strが変わっていきますが、 たまたま同じ検索文字列が続いたときにHITしなかったため、 上の簡易プログラムで試してみたところです。

    • ベストアンサー
    • Perl
  • シェル関数引数のスペース文字列をgrepに

    下記のシェル関数 arg_space() 内で、grepを使いたいのですが。 'aaa bbb' などのスペースを含む文字列を引数として渡すとスペース後の文字列がファイル名と 認識されてしまいます。 -- arg_space.sh -- #!/bin/bash CHK_STR='aaa bbb' FILE_NAME='data/aaa.txt' function arg_space() { return `grep -c $1 $2` } arg_space $CHK_STR $FILE_NAME if [ $? -ge 1 ]; then echo 'Match !!' else echo 'No match.' fi exit 0 ------------------ ]# ./arg_space.sh grep: bbb: No such file or directory Match !! スペース文字を、grep に区切り文字として認識させないようにする 方法を教えて 頂けないでしょうか。 -- data/aaa.txt -- aaa bbb ccc ddd ---------------

  • grepにマッチした正規表現の文字列を取得したい

    grepにマッチした正規表現の文字列を取得し、マッチした文字列を 一覧で取得したいのですが、方法がわかりません。 ※例 grep [0-9][0-9][0-9][0-9][0-9] 検索ファイル名 > 出力ファイル名 不明点あればお知らせください。 よろしくお願いします。

  • エクセル関数で分からない事があります

    文字列の中に特定の文字を含んだものを検索し 検索でヒットしたものと同じ行にある 数字を全て合計した数を返したいのです。 COUNTIFを使って データの中から、文字列の中に特定の文字を含んだセルが 何個あるかは調べられたのですが INDEX、MATCH、IF、SUMIF色々試したのですが どうもうまくいきません・・・。 どなたか関数技を伝授してください(>_<)

  • ユーザ管理データベース

    教えてgooやYahooで使われているようなマイページ プログラムをPerlとテキストファイルで作りました。 それはそれで一応できあがったのですが、 これを今度はデータベースソフトで作り直したいと 考えています。データベースはいまのところACCESSです。将来的にはデジエなんかよさそうに思っています。 Perlで組んでいると流れはわかるのですが、 ACCESSだとイマイチ流れがわかりません。 Perlだと、 ユーザID、PW入力 ↓ ユーザデータを管理しているファイルとマッチング ↓ 合致しているユーザとデータを保持しているファイルとマッチング ↓ マッチしているユーザの情報を画面表示 という流れです。 AさんにはAさんの情報が見られるように、BさんにはBさんの情報が見られるようにしたいのです。 データベースでやれば簡単にできそうな流れなのですが、ユーザIDとパスワード入れてマッチングするところでなにも思い浮かびません。 簡単なサンプルプログラムなどあるととても参考になります。またはヒントでも結構なのでご教授ください。

  • 検索CGIについて

    始めまして よろしくお願いします 今サーチスクリプトを作成しているのですが 「X件見つかりました」 のようにするにはどのようなコーティングにすればいいのでしょうか? 自分なりにはやってみたもののあまり上手くできません 現在のコーティングは インデックス関数でマッチさせています また失敗の原因はマッチの判定の回数が表示されてしまいます 言語はperlです よろしくお願いします

    • ベストアンサー
    • Perl
  • CGIの正規化

    Perlでプログラムを組んでいます。 正規化って便利なものがあるのは判ったのですが、 使い方がいまいち判りません。 例えば 空白から@までの文字を取得したい場合は どのように書いたら良いのでしょうか □をスペースとして abcf□defgh@ertyh□asdfg 見たいな文字列で defgh を取得したいのです。  良かったら教えてください。

    • 締切済み
    • CGI