我想这样做:
我需要创建一个使用以下操作符的搜索引擎解析器:
- 苹果和橙子
- 苹果或橙子(或运算符)
- 苹果和不橙子(和不操作符)
- " 苹果 " (引用操作符)
- 苹果和(橙子或梨)(括号运算符)
- 应用程序*(星号操作符)
使用一些preg_replace,我设法将字符串转换为数组,然后我解析该数组以获得MySQL查询。但我不喜欢那样,而且很不稳定!
我在网上搜索了一些脚本,这样做,我没有任何运气!
有人能帮我实现这个吗??
谢谢
好的,这将是一个很大的答案。
我认为你需要的是一个解析器生成器。生成代码以根据给定语法解析文本的软件。这些解析器通常有两个主要组件:词法分析器和解析器。词法分析器识别令牌(单词),解析器根据语法检查令牌顺序是否正确。
在词法分析器中,您应该声明以下令牌
TOKENS ::= (AND, OR, NOT, WORD, WORDSTAR, LPAREN, RPAREN, QUOTE)
WORD ::= '/w+/'
WORDSTAR ::= '/w+'*/'
语法应该这样定义:
QUERY ::= word
QUERY ::= wordstar
QUERY ::= lparen QUERY rparen
QUERY ::= QUERY and QUERY
QUERY ::= QUERY or QUERY
QUERY ::= QUERY and not QUERY
QUERY ::= quote MQUERY quote
MQUERY ::= word MQUERY
MQUERY ::= word
该语法定义了一种具有您需要的所有特性的语言。根据您使用的软件,您可以定义处理每个规则的函数。这样,就可以将文本查询转换为sql where子句。
我不太喜欢php,但是我在网上搜索了一个解析器生成器,PHP_ParserGenerator出现了。
请记住,随着数据库的增长,这些查询可能会成为结构化存储系统的问题。
您可能想要尝试全文搜索引擎,它允许您执行此操作以及与文本搜索相关的许多其他功能。这就是IndexTank的工作原理
首先,将所有数据库记录(或搜索方言中的"索引")添加到IndexTank。
$api = new ApiClient(...);
$index = $api->get_index('my_index');
foreach ($dbRows as $row) {
$index->add_document($row->id, array('text' => $row->text));
}
之后,您可以使用您想要的所有操作符在索引中搜索
$index = $api->get_index('my_index');
$search_result = $index->search('Apples AND Oranges');
$search_result = $index->search('Apples OR Oranges');
$search_result = $index->search('Apples AND NOT Oranges');
$search_result = $index->search('"apples oranges"');
$search_result = $index->search('Apples AND ( Oranges OR Pears )');
$search_result = $index->search('Appl*');
我希望我回答了你的问题。
同样,这也不完全是你想要的,但可能接近:MySQL全文搜索。
- http://devzone.zend.com/article/1304
- http://www.artfulcode.net/articles/full-text-searching-mysql/
- http://jeremy.zawodny.com/blog/archives/000576.html
你看ANTLR了吗
你可以自制一些像下面这样的东西(重要: $search
字符串必须首先被消毒,否则你会被黑客攻击)…
if (substr($search[0]=='*' and substr($search,-1)=='*') {
// *ppl*
$query = "SELECT * FROM `table` WHERE `field` LIKE (%'". str_replace('*','',$search) ."%')";
} elseif (substr($search,-1)=='*') {
// Appl*
$query = "SELECT * FROM `table` WHERE `field` LIKE ('". str_replace('*','',$search) ."%')";
} elseif ($search[0]=='*') {
// *Appl
$query = "SELECT * FROM `table` WHERE `field` LIKE ('%". str_replace('*','',$search) ."')";
} elseif (substr_count($search,'"')==2) {
// " Apples " ... just remove the "
$query = 'SELECT * FROM `table` WHERE `field` = "'. str_replace('"','',$search) .'"';
} elseif (strpos($search,')') or strpos($search,'(')) {
// uh ... something more complex here
$query = '#idunno';
} else {
// the rest
$query = 'SELECT * FROM `table` WHERE `field` = "'. $search .'"';
$search = array(
' AND ',
' OR ',
' AND NOT '
);
$replace = array(
'" AND `field` = "',
'" OR `field` = "',
'" AND `field != "'
);
str_replace($search,$replace,$query);
}
试试:http://www.isearchthenet.com/isearch/index.php
从自述:- 搜索通常使用"可能包含"单词。匹配要求输入的任何单词都出现在页面上。
- 您可以搜索包含特定单词的页面,方法是在页面前面加一个加号。只有包含该单词的页面才会显示。
- 您可以忽略包含特定单词的所有页面,只需在其前面加上减号(-)。任何包含该词的页面都不会显示在搜索结果中。
- 可以用双引号(")括起来搜索特定的短语。只有包含该短语的页面才会显示。
易于安装和使用。还可以看看http://sphinxsearch.com/-最强大的引擎,但不适合新手。