我们已经使用 MySQL 全文搜索好几年了,但需求已经发生了变化。我们希望将 AND/OR/NOT 参数解析为 MySQL 能够理解的形式。我写了一个单元测试,很明显这很复杂。
我相信更多的人会遇到这个问题,所以我想一定有某种图书馆能够为我做到这一点。我试过谷歌,但不幸的是,我找不到这样的图书馆。有人知道好的吗?
该库应该能够处理引号、括号、AND/OR/NOT 运算符,在我们的例子中,它应该默认为 AND 而不是 OR(如果没有设置运算符)。以下是我的一些预期结果:
- 'ict' 变成 '+ict'
- 'ict it' 变成 '+ict +it'
- 'ict OR it' 变成 'ict it'
- '不是 ict' 变成 '-ict'
- 'it NOT ict' 变成 '+it -ict'
- 'web AND (ict OR it)' 变成 '+web +(ict it)'
- 'ict OR (it AND web)' 变成 'ict (+it +web)'
- 'ict NOT (ict AND it AND web)' 变成 '+ict -(+ict +it +web)'
- 'php OR (NOT web NOT embedded ict OR it)' 变成 'php (-web -embedded ict it)'
- '(web OR embedded) (ict OR it)' 变成 '+(web embedded) +(ict it)'
- 开发 AND (web OR (ict AND php))' 变为 '+develop +(web (+ict +php))'
- '"ict' 变成 '+"ict"'
- '"ict OR it"'保持 '+"ict OR it"'
这是我们过去几年使用的功能(不能正常工作):
/**
* Parses search string.
* @param string $s The unparsed search string.
* @return string $s The parsed search string.
*/
public function parseSearchString( $s )
{
// Place a space at the beginning.
$s = ' ' . $s;
// AND - Remove multiple spaces, AND, &.
$s = preg_replace( '/\s\s+/', ' ', $s );
$s = preg_replace( '/\sAND\s/i', ' ', $s );
$s = preg_replace( '/\s&\s/', ' ', $s );
// OR - Make replacements. Execute double, so we replace all occurences.
$s = preg_replace( '/(\w+)\s(?:OR|\|)\s(\|?\w+)/i', '|\\1|\\2', $s );
$s = preg_replace( '/(\w+)\s(?:OR|\|)\s(\|?\w+)/i', '|\\1|\\2', $s );
$s = preg_replace( '/(\w+)\s*(?:\\\|\\/)\s*(\|?\w+)/i', '|\\1|\\2', $s );
$s = preg_replace( '/(\w+)\s*(?:\\\|\\/)\s*(\|?\w+)/i', '|\\1|\\2', $s );
// NOT
$s = preg_replace( '/\bNOT\s(\w+)/i', '|-\\1', $s );
// Quoted strings.
$s = preg_replace( '/\s"/', ' +"', $s );
// Place + in front of words.
$s = preg_replace( '/\s(\w+)/', ' +\\1', $s );
// Replace | to spaces.
$s = preg_replace( '/\|/', ' ', $s );
return trim( $s );
}