SQL文をPHPの正規表現関数を使って書き換える。この正規表現がなかなかうまくかけなくてハマッタ。
元のクエリの対象部分はこんな感じ。
hoge LIKE ‘%bar%’ AND fuga LIKE ‘%www%’
お題は、ANDの前の部分( hoge LIKE ‘%bar%’) を捕まえて、以下のようにしたい。もちろんbar や wwwは不定。
(SELECT id FROM xxx WHERE hoge LIKE ‘%bar%’) AND fuga LIKE ‘%www%’
そこで、最初書いたパターンがこれ。
“hoge LIKE ‘%.*%’”
確かに最初はうまく動いているかに見えたんだけど、これだと、最初のお題の文章全体がヒットしちゃうのね。つまり、hoge LIKE ‘% の % から始まって、 www%’ の %までが 「.*」で表現されていることになる。結局お題の文章全体がヒットしてしまい、期待通りではないことが判明。これを最長一致というのね。ってことは俺がやりたいのは、最短一致だな。mb_ereg_replace を使うと第4引数で s を指定すると最短一致になるらしいが、できれば正規表現で済ませたいので、もう一踏ん張り。
ここでポイントは、’%bar%’ の最初の % でヒットしたら、次の%が出たらもう区切りの場所が近いということだから、「%以外の0文字以上で、最後に%がある」 って考えればよいとうこと。
“hoge LIKE ‘%[^%]*%’”
これがなかなか思いつかないもので、たっぷり2時間悩んだ。週末で、昨日から寝不足だったけど、気持ちよく週末を迎えるためにはなんとしてもクリアしておきたい箇所だった。
最終的には、以下のような感じでanswer が得られた。
$string = ” hoge LIKE ‘%bar%’ AND fuga LIKE ‘%www%’ “;
$pattern = “hoge LIKE ‘%[^%]*%’”;
$replacement = ‘(SELECT id FROM xxx WHERE \\0)’;
$answer = ereg_replace($pattern, $replacement, $string);
今回も大助かりの、ReJax Easiest Regular Expression Tester. Ever. このサイトを知らなかったら、あきらめて寝るが、落ち着かない週末になるところだった。
天気は金曜日から雨だけど、なにやらすごく気分がいいぞ?!
一杯ヒッカケテ寝ますかね。