对于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