搜索引擎关键词解析器

时间:2011-07-29 11:26:06

标签: php operators search-engine text-parsing

这是我想要做的:

我需要创建一个使用以下运算符的搜索引擎解析器:

  • 苹果 AND 橙子(AND运营商)
  • 苹果 OR 橙子(OR运营商)
  • 苹果 AND NOT 橙子(AND NOT运营商)
  • 苹果(报价运算符)
  • 苹果 AND(橙子 OR (圆括号运算符)
  • Appl *(明星运营商)

使用一些preg_replace,我设法将字符串转换为数组,然后解析此数组以获取MySQL查询。 但我不喜欢这种方式而且非常不稳定!

我在网上搜索了一些这样做的脚本,我没有运气!

有人可以帮我实现吗??

由于

5 个答案:

答案 0 :(得分:3)

好的,这将是一个很大的答案。

我认为你需要的是一个解析器生成器。一种软件,它根据给定的语法生成解析文本的代码。这些解析器通常有两个主要组件:词法分析器和解析器。词法分析器识别TOKENS(单词),解析器根据你的语法检查令牌顺序是否正确。

在词法分析器中,您应该声明以下标记

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*');

我希望我回答你的问题。

答案 1 :(得分:1)

答案 2 :(得分:0)

你看过ANTLR

了吗?

答案 3 :(得分:0)

您可以自制以下内容(重要提示: $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);
}

答案 4 :(得分:-1)

试试这个:http://www.isearchthenet.com/isearch/index.php

自述文件:

  • 搜索通常使用“可能包含”字词执行。匹配要求输入的任何单词出现在页面上。
  • 您可以在前面添加加号(+)来搜索包含特定单词的页面。只会显示包含该单词的页面。
  • 您可以通过在前面添加减号( - )来忽略包含特定单词的所有页面。任何包含该单词的页面都不会显示在搜索结果中。
  • 您可以通过用双引号(“)括起来搜索特定短语。只会显示包含该精确短语的页面。

易于安装和使用。另请参阅http://sphinxsearch.com/ - 最强大的引擎,但不是新手。