简体   繁体   English

PHP从MySQL全文搜索中突出显示多项结果

[英]PHP Highlight Multiterm Results from MySQL Full Text Search

A lot of people have asked questions about how to highlight search terms in the results from a MySQL Full Text Search, but the solutions that I have found do not appear to be sufficient. 许多人提出了有关如何在MySQL全文搜索的结果中突出显示搜索词的问题,但是我发现的解决方案似乎还不够。 The MySQL Full Text Search supports quoted multi-word search targets and ignores any punctuation. MySQL全文搜索支持带引号的多字搜索目标,并忽略任何标点符号。 Thus, on my search form the user could enter the quoted term "quick brown" and MySQL will also return rows that include "quick, brown" (for example), but not "quick and brown". 因此,在我的搜索表中,用户可以输入带引号的术语“快速棕色”,而MySQL还将返回包含“快速棕色”(例如)但不包括“快速棕色”的行。 So when highlighting the search target in the returned text, it seems you need to do some regular expressions to make sure you identify all instances of the target. 因此,当在返回的文本中突出显示搜索目标时,似乎需要执行一些正则表达式以确保标识出目标的所有实例。 What I have so far is this, where $targ contains a possibly multiword search term such as "quick brown" (but without the quotes), and $blob is the large string of text that we are searching through. 到目前为止,我所知道的是,$ targ包含一个可能的多字搜索词,例如“ quick brown”(但不带引号),而$ blob是我们正在搜索的大文本字符串。 It works by replacing any spaces in the search target with a regular expression that matches any non-alphanumeric string. 它通过用匹配任何非字母数字字符串的正则表达式替换搜索目标中的任何空格来工作。

$pattern = '/' . str_replace(" ", '[^A-Za-z0-9\"]', $targ) . '/i';
$replacement = '<span class="hilite">' . $targ . '</span>';
$blob = preg_replace($pattern, $replacement, $blob);

This mostly works, but with one unfortunate side-effect. 这通常有效,但是有一个不幸的副作用。 It actually deletes the extra punctuation from the full string. 实际上,它会从完整字符串中删除多余的标点符号。 So if $blob contains the string "quick, brown" this gets changed to 因此,如果$ blob包含字符串“ quick,brown”,则将其更改为

<span class="hilite">quick brown</span>

So it succeeded in adding the span tags around the term, but in the process, it removed the comma. 因此,它成功地在术语周围添加了span标签,但在此过程中,它删除了逗号。

I think the solution probably involves using preg_replace with wildcards, but one difficulty is that $targ could have varying numbers of words in it. 我认为解决方案可能涉及对通配符使用preg_replace,但是一个困难是$ targ中可能包含不同数量的单词。

Any suggestions? 有什么建议么? Thanks! 谢谢!

You can do this pretty easily with capture groups. 您可以使用捕获组轻松完成此操作。 Also when accepting input from the user for a pattern it's a good idea to escape it before using it. 同样,当接受用户输入的模式时,最好在使用它之前对其进行转义。

<?php
$source = 'quick, brown" (for example), but not "quick and brown". So whe';
$test = "QUICK BROWN";
$temp = explode(" ", $test);
// use preg_quote to escape the literal strings
$temp = array_map(function ($val) { return preg_quote($val, "~");}, $temp);
// stitch the literals together with the variable pattern 
$pattern = '~('.implode("[^A-Za-z0-9]+", $temp).')~i';
// here the $1 means the result of the first capture group... 
// capture group is denoted in the pattern as the text in (). 
echo preg_replace( $pattern , '<span class="hilite">$1</span>', $source );

You can see this running here . 您可以在这里看到运行情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM