« Snow LeopardにしたらCコンパイラーが | トップページ | Automatorでlame使用のMP3エンコーダのドロップレット その2(邪道編) »

2009年9月14日 (月)

簡単なAND検索の方法を

教えてほしいなんて、そんなこと自分で考えな!と普段だったら言うところですが、かわいい研修生にグリーンの瞳で見つめられながら言われては絶対に断れないですよね(しかしこの子は美人だ...)

ということで久々のスクリプトネタです。

喜んでしかたがないのでどのスクリプトでも通用しそうな方法をPerl様を使って教えました。これけっこう今までも訊かれることが多かったので、色々なやり方がある中で初心者の方にもわかりやすい方法だけを少しだけ書いておきます。まあ実際にはこのような形で使われることはめったにないでしょうが。

前置きとして検索する単語群と検索の対象になる文はどちらも配列に入っているものとすることにします。例では検索する単語群の配列を@tangogun、検索の対象になる文が行ごとに入った配列を@bunとし、全ての検索語にマッチした行だけをプリントすることにします。JavaScriptでも他のスクリプト言語でも似たようなことをすれば(番外編を除いて)動くはずです。

その1 検索する単語群の入った配列の要素数とマッチした回数をチェックし、二つの値が等しい場合にプリントする方法

foreach $gyou(@bun){
  $kazu = 0;
  foreach $tango(@tangogun){
    if ($gyou =~ /$tango/){
      $kazu++;
    }
  }
  if ($kazu == $#tangogun + 1){
    print "$gyou";
  }
}

コマンドラインでしたらcatで検索対象の文を読み込んで(別にcatを使う必要は全くないですがパイプライン処理だと想定して)Perlのオプションで-neを指定すれば下記の例のようにそのまま使えます。例では検索単語群は"Finland"、"restaurant"、"Kamome"ということにしておきます。

cat restaurantlist.txt | perl -ne '$kazu = 0;@tangogun=("Finland", "restaurant", "Kamome");foreach $tango(@tangogun){if(/$tango/){$kazu++;}}if($kazu == $#tangogun + 1){print;}'

その2 検索する単語がマッチすれば的(まと)という変数に当たりマーク与え次の検索語へ進み、そうでなければハズレマークを与えてlastでループから抜け出し、最終的に的(まと)が当たりマークだったらプリントする方法

foreach $gyou(@bun){
  $kazu = 0;
  foreach $tango(@tangogun){
    if ($gyou =~ /$tango/){
      $mato='atari';
    }else{
      $mato='hazure';
      last;
    }
  }
  if ($mato eq 'atari'){
    print "$gyou";
  }
}

こちらもコマンドラインでやるにはその1と同様にcatで検索対象の文を読み込んでPerlのオプションで-neを指定すれば簡単にできます。

cat restaurantlist.txt | perl -ne '$kazu = 0;@tangogun=("Finland", "restaurant", "Kamome");foreach $tango(@tangogun){if(/$tango/){$mato='atari';}else{$mato='hazure';last;}}if($mato eq 'atari'){print;}'


その3(番外編)検索単語群を「(?=.*Finland)(?=.*restaurant)(?=.*Kamome)」という感じに「(?=.*〜)」を使って連結して検索にかけるとあ〜ら不思議、上記2例と同じ結果が得られます。これは非常に有名ですがPerlでやると正直遅いです。ただSnow Leopardの入ったインテルマックだと速度差は気づきませんけどね。これを使うとPerl様でも全く歯が立たないくらい激速なのはSafariの(WebKitの)JavaScriptです。昔のFirefoxでは(1.Xの頃ね)動きませんでしたが今のバージョンではわかりません。例では検索単語群を連結したものを入れた変数$renketsuを使いました。

$renketsu = '(?=.*Finland)(?=.*restaurant)(?=.*Kamome)';
foreach $gyou(@bun){
  if ($gyou =~ /$renketsu/){
    print "$gyou";
  }
}

コマンドラインではクオート問題を回避するためにq//などを使ってやると下記のようにやると良いでしょう。

cat restaurantlist.txt | perl -ne '$renketsu=q/(?=.*Finland)(?=.*restaurant)(?=.*Kamome)/;if(/$renketsu/){print;}'

さっ、かわい子ちゃんと一緒にお茶してこよ

« Snow LeopardにしたらCコンパイラーが | トップページ | Automatorでlame使用のMP3エンコーダのドロップレット その2(邪道編) »

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: 簡単なAND検索の方法を:

« Snow LeopardにしたらCコンパイラーが | トップページ | Automatorでlame使用のMP3エンコーダのドロップレット その2(邪道編) »

2019年9月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          

最近のトラックバック