我已经阅读了很多类似的文章,但是都没有解决我的问题,这很可能是由于我缺乏足够的知识,所以请多多包涵。
我的术语词典中的搜索选项之一是“仅整个单词”。起初我在使用
WHERE ".$source." RLIKE '[[:<:]]".$keyword."[[:>:]]'
但是,当第一个$keyword
或第二个WHERE ".$source." REGEXP '[[:<:]]".$keyword."[[:>:]]'
的单词全部不匹配时,则无法匹配整个单词。然后我发现了
WHERE ".$source." REGEXP '(^| )".$keyword."( |$)'
和
[[:<:]]
时
我刚刚在PhpMyAdmin中测试了以上两种情况,发现前者执行时间为0.0740秒,而后者花费的时间是后者的两倍,即0.1440秒,所以我想我应该坚持使用前者。
最令我困扰的是结果的巨大差异,例如搜索一个单词(“工具”):
在PhpMyAdmin中使用[[:>:]]
和(^| )
字边界将返回34个结果。
在PhpMyAdmin中使用( |$)
和foreach($keywords as $keyword) {
$query = $db->query("SELECT * FROM ".DICTIONARY_TABLE." " .
"JOIN ".DICTIONARY_THEMES." ON ".DICTIONARY_TABLE.".theme_id = ".DICTIONARY_THEMES.".theme_id ".
"LEFT JOIN ".DICTIONARY_DEFINITIONS." ON ".DICTIONARY_TABLE.".term_id = ".DICTIONARY_DEFINITIONS.".term_id ".
"WHERE ".DICTIONARY_TABLE.".".$source." REGEXP '(^| )".$keyword."( |$)'".
//"WHERE ".DICTIONARY_TABLE.".".$source." REGEXP '[[:<:]]".$keyword."[[:>:]]'".
" ORDER BY ".DICTIONARY_TABLE.".theme_id, ".DICTIONARY_TABLE.".".$source."");
}
返回26个结果。
在我的PHP脚本中运行#1正则表达式会返回34个结果(这是正确的数字)。
这是整个MySQL块:
SELECT * FROM `asphodel_dictionary_terms` WHERE english REGEXP '[[:<:]]cutting[[:>:]]';
SELECT * FROM `asphodel_dictionary_terms` WHERE english REGEXP '[[:<:]]tool[[:>:]]'
我已经注释掉了我不使用的搜索选项。
现在,如果我尝试两个关键字,例如“切割工具”,我仍然在页面中获得34个结果。我不确定我是否在PhpMyAdmin中正确执行此操作:
(^| )
这将为“切割”返回44个结果,为“工具”返回34个结果。使用DICTIONARY_THEMES
...的查询分别返回37 + 26个结果。
任何能帮助我解决问题的反馈将不胜感激!
该数据库在主表中总共包含109,000个条目,在DICTIONARY_DEFINITIONS
表中有82个主题,在{{1}}表中有727个条目。不是一个庞大的数据库,它也不会变得更大。
答案 0 :(得分:1)
由于两个正则表达式不相同,因此得到的结果不同。
(^| )
的含义是:字符串的开头或空格(( |$)
在字符串的末尾具有相同的含义)。
[[:<:]]
和[[:>:]]
是单词边界:从概念上讲,它是指分隔单词的字符,通常regex引擎将其解释为类似:除数字,字母或下划线。
因此,基本上第一种模式比第二种模式更具限制性(空格,字符串的开头和结尾是单词边界,但还有其他限制)。
如果要搜索的关键字不止一个,则需要重复正则表达式匹配项,例如:
WHERE
".$source." RLIKE '[[:<:]]".$keyword1."[[:>:]]'
OR ".$source." RLIKE '[[:<:]]".$keyword2."[[:>:]]'
或通过组合关键字创建新的正则表达式:
WHERE
".$source." RLIKE '[[:<:]](".$keyword1.")|(".$keyword2.")[[:>:]]'
NB:出于搜索要求,您应该考虑使用MySQL Full Text Search,其主要目的是搜索完整的单词(不过有先决条件)。