我正在创建一个简单的搜索我的应用程序。
我正在使用PHP正则表达式替换(preg_replace)来查找搜索词(不区分大小写)并在搜索词周围添加<strong>
标记。
preg_replace('/'.$query.'/i', '<strong>$0</strong>', $content);
现在我对正则表达式不是最好的。那么,我将如何添加到正则表达式中以不替换href
锚标记中的搜索词?
如果有人搜索“信息”,则不会更改指向“http://something.com/this_<strong>
info</strong>
/index.html”的链接
答案 0 :(得分:1)
我相信你需要条件子模式]才能达到这个目的:
$query = "link";
$query = preg_quote($query, '/');
$p = '/((<)(?(2)[^>]*>)(?:.*?))*?(' . $query . ')/smi';
$r = "$1<strong>$3</strong>";
$str = '<a href="/Link/foo/the_link.htm">'."\n".'A Link</a>'; // multi-line text
$nstr = preg_replace($p, $r, $str);
var_dump( $nstr );
$str = 'Its not a Link'; // non-link text
$nstr = preg_replace($p, $r, $str);
var_dump( $nstr );
string(61) "<a href="/Link/foo/the_link.htm">
A <strong>Link</strong></a>"
string(31) "Its not a <strong>Link</strong>"
PS:以上正则表达式还负责多行替换,更重要的是忽略了匹配 href,而忽略了<
和>
中包含的任何其他HTML实体。
编辑:如果您只想排除hrefs
而不是所有html实体,请在我的回答中使用此模式而不是上述模式:
$p = '/((<)(?(2).*?href=[^>]*>)(?:.*?))*?(' . $query . ')/smi';
答案 1 :(得分:0)
我不是100%你最终在这之后,但是从我能做到的,它是一种“搜索短语”突出显示设施,可以强调关键词。如果是这样,我建议看看CodeIgniter中的Text Helper。它提供了一个很好的小函数叫highlight_phrase
,这可以做你想要的。
功能如下。
function highlight_phrase($str, $phrase, $tag_open = '<strong>', $tag_close = '</strong>')
{
if ($str == '')
{
return '';
}
if ($phrase != '')
{
return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str);
}
return $str;
}
答案 2 :(得分:0)
您可以使用条件子模式,请参阅此处的说明:http://cz.php.net/manual/en/regexp.reference.conditional.php
preg_replace("/(?(?<=href=\")([^\"]*\")|($query))/i","\\1<strong>\\2</strong>",$x);
在你的情况下,如果你有完整的HTML,而不仅仅是href=""
,使用'e'修饰符有一个更简单的解决方案,它允许你使用PHP代码替换匹配
function termReplacer($found) {
$found = stripslashes($found);
if(substr($found,0,5)=="href=") return $found;
return "<strong>$found</strong>";
}
echo preg_replace("/(?:href=)?\S*$query/e","termReplacer('\\0')",$x);
请参见示例#4 http://cz.php.net/manual/en/function.preg-replace.php
如果您的表达式更复杂,您甚至可以在termReplacer()
内使用regExp。
PHP中存在一个小错误:$found
中的termReplacer()
参数需要被剥离!