正则表达式负前瞻/后瞻以从查找和替换中排除HTML

时间:2013-03-20 14:45:32

标签: php html regex html-parsing preg-replace

我的网站上有一项功能,搜索结果会在搜索结果中突出显示搜索查询。但是,网站搜索的某些字段中包含HTML。例如,假设我的搜索结果包含<span>Hello all</span>。如果用户搜索了字母a,我希望代码返回<span>Hello <mark>a</mark>all</span>而不是现在返回的凌乱的<sp<mark>a</mark>n>Hello <mark>a</mark>ll</sp<mark>a</mark>n>

我知道我可以在preg_replace()中使用否定的lookbehinds和lookaheads来排除a介于<>之间的所有实例。但是我该怎么做?正则表达式是我的弱点之一,我似乎无法想出任何有用的工作。

到目前为止,我得到的是:

$return = preg_replace("/(?<!\<[a-z\s]+?)$match(?!\>[a-z\s]+?)/i", '<mark>'.$match.'</mark>', $result);

但它似乎不起作用。有什么帮助吗?

2 个答案:

答案 0 :(得分:1)

如果你想使用正则表达式,只需要一个简单的否定前瞻(假设格式良好的标记,标签内或标签之间没有<>

$return = preg_replace("/$match(?![^<>]*>)/i", '<mark>$0</mark>', $result);

$match中的任何特殊正则表达式字符都需要正确转义。

答案 1 :(得分:1)

使用正则表达式来解析像HTML这样的复杂语言被认为是不好的做法。有足够的技巧和耐心,以及先进的正则表达式引擎,它可能是可能的,但潜在的陷阱是巨大的,性能不太可能是好的。

更好的解决方案是使用dom解析器,例如PHP的内置DOMDocument类。

这是can be found here in the answer to this related SO question的一个很好的例子。

希望有所帮助。