對於MySQL的那些framiliar,它提供了通過正則表達式(POSIX風格)搜索的能力。我需要一種先進的搜索方式,而我的後端是mysql,所以這是合乎邏輯的選擇。問題是,我如何基於輸入構建整個mysql查詢?這是我希望能夠處理查詢的類型:
- 確切的詞
- 子字符串匹配匹配(我用像「%WORD%」這樣做)
- 通過子串排除比賽
- 通過確切的詞匹配
一個簡單的正則表達式查詢看起來像排除:
select * from TABLE where ROW regexp'[[:<:]] bla [[:>:]]'和ROW regexp'foo';
這將查找字符串「喇嘛」的精確匹配,這意味着不是作爲一個子字符串,然後匹配子字符串「foo」的地方。
因此,首先,第1項和第4項是精確的單詞匹配,我希望能夠通過用引號括住單詞來做到這一點。讓我們來設置我們需要的變量,然後做報價匹配:
$newq = $query; # $query is the raw query string
$qlevel = 0;
$curquery = "select * from TABLE where "; # the beginning of the query
$doneg = 0;
preg_match_all("/\"([^\"]*)\"/i", $query, $m);
$c = count($m[0]);
for ($i = 0; $i < $c; $i++) {
$temp = $m[1][$i]; # $temp is whats inside the quotes
然後,我希望能夠排除的話,用戶應該能夠用破折號開始這個詞來做到這一點( - ),而對於確切的單詞匹配,這必須在引號內。第二場比賽是擺脫 - 在查詢前面。
if (ereg("^-", $temp)) {
$pc = preg_match("/-([^-]*)/i", $m[1][$i], $dm);
if ($pc) {
$temp = $dm[1];
}
$doneg++;
}
現在我們將$ temp設置爲符合posix的精確匹配,然後構建mysql查詢的這一部分。
$temp = "[[:<:]]".$temp."[[:>:]]";
if ($qlevel) $curquery .= "and "; # are we nested?
$curquery .= "ROW "; # the mysql row we are searching in
if ($doneg) $curquery .= "not "; # if dash in front, do not
$curquery .= "regexp ".quote_smart($temp)." ";
$qlevel++;
$doneg = 0;
$newq = ereg_replace($m[0][$i], "", $newq);
}
變量$ newq具有搜索字符串的引號休息,減去一切,所以剩下什麼剩下的無論是在2和3下降現在我們可以順利通過子字符串搜索項目,基本上都與上面相同。
$s = preg_split("/\s+/", $newq, -1, PREG_SPLIT_NO_EMPTY); #whitespaces
for ($i = 0; $i < count($s); $i++) {
if (ereg("^-", $s[$i])) { # exclude
sscanf($s[$i], "-%s", $temp); # this is poor
$s[$i] = $temp;
$doneg++;
}
if ($qlevel) $curquery .= "and ";
$curquery .= "ROW "; # the mysql row we are searching in
if ($doneg) $curquery .= "not ";
$curquery .= "regexp ".quote_smart($s[$i])." ";
$qlevel++;
$doneg = 0;
}
# use $curquery here in database
變量$ curquery現在包含我們構建的mysql查詢。你會注意到在這裏使用quote_smart,這是一個來自php.net的mysql最佳實踐。這是此代碼中唯一提到的安全性。您需要對輸入進行自己的檢查以確保沒有錯誤的字符,我只允許使用字母數字和其他字符。如果沒有先解決這個問題,請不要使用此代碼。
那麼這取決於你的要求。用戶是否必須搜索所有標準?還是隻有一個標準?它也取決於你的模式。也許用你的模式更新你的問題一些樣本數據,一些樣本結果和你想要多標準工作的描述;以及您嘗試過的方法以及您遇到的問題/錯誤。 – liquorvicar 2012-03-28 06:04:25
用戶可以選擇是搜索一個,兩個還是全部標準。 – 2012-03-28 06:09:10