脱力系備忘録BloG ホーム »PHPとPostgreSQLで正規表現を使ったAND検索

PHPとPostgreSQLで正規表現を使ったAND検索  

PostgreSQLで文字列のAND検索を正規表現でできんかなあ。

と思ったらできた。
PostgreSQLで正規表現を使うのは
POSIX正規表現というものがあります。これはPostgreSQLのドキュメントを読んだらすぐわかります。
問題は正規表現のANDです。
こちらで説明されていますが、正規表現の「位置指定子」というものを使うと実現できます。
できます。と自信を持って書いてますが、「位置指定子」がどういうものかよくわかってません。
まあとにかくこういう記号なんだそうです「?=」。

具体的にPostgreSQLで書くと

select * from tablename where mojiretsu ~ '^(?=.*WORD1)(?=.*WORD2)';

こうなります。
「mojiretsu」文字列の中に「WORD1」と「WORD2」があるとマッチします。
「(?=.*WORD)」これを増やせば3つ、4つとAND条件を増やせます。
ちなみに、

'^(?=.*WORD2)(?=.*WORD1)'

でも同じ結果になります。
なぜなら、この正規表現が
文字列先頭から何かゼロ個以上文字があってWORD1がある。そして、文字列先頭から何かゼロ個以上文字があってWORD2がある。ならマッチ」
だからです。

ということで、PostgreSQLでの表記はこれでできましたが、PHPに組み込む場合はもう一工夫が必要です。
おそらくこれを使う場面はユーザーに検索文字列を入力してもらって、それを検索するという使い方になると思います。
その場合、ユーザーはどんな文字を入力してくるかわかりません。そのままSQLに当てはめるのは危険です。
そこで、正規表現のエスケープ処理関数を使います。

preg_quote()

という関数です。
具体例としては

$words = '^';
foreach (explode(' ', $ユーザー入力文字列) as $value) {
  $words .= sprintf('(?=.*%s)', preg_quote($value));
}

このような流れでしょうか。
ここでは半角空白を検索単語の区切りとしています。
そして、これをPDOを使ってDBアクセスするとしたら、

$sth = $PDO->prepare('select * from tablename where mojiretsu~*:MOJIRETSU');
$sth->bindValue(':MOJIRETSU', $words, PDO::PARAM_STR);
$sth->execute();
$result = $sth->fetchAll();

このようになると思います。
なお、「mojiretsu~*:MOJIRETSU」の部分の「*」はPostgreSQLマニュアルのPOSIX正規表現の項を見てもらうとわかりますが、「大文字小文字の判別をしない」という記号です。

まあ、これで文字列検索ができるのですが、速度的にはどうなんだろう。ちょっと遅い気もしますが、まあ、こういう正規表現も書けるよということで終わろうと思います。
正規表現は奥が深すぎて理解がおいつかない・・・。

※PHPとPostgreSQLの組み合わせで、もっとはっえー文字列AND検索方法があるよ!って方はおせーて。
関連記事

category: データベース PHP

この記事へのコメント

コメントの投稿

非公開コメント

コメントは全て管理人が内容を確認してから表示されます(非公開コメント除く)。
内容によっては表示されない場合がありますことご了承願います。

プロフィール

お問い合わせ

最新記事

最新コメント

▲ Pagetop