如何在 preg_replace 中排除 HTML 标签
提供的代码尝试使用 preg_replace 突出显示字符串中的搜索结果。然而,字符串中 HTML 标签的存在带来了挑战,因为替换操作无意中标记了标签本身,从而破坏了 HTML 结构。
解决方案:采用基于 DOM 的方法
正则表达式并不是解析 HTML 的理想工具。相反,请考虑使用 DOM(文档对象模型)和 DOMXPath 来导航字符串的 XML 结构。
DOMXPath 允许您搜索包含特定文本的元素,而忽略 XML 元素。这允许您隔离相关的文本节点并将它们包装在所需的跨度标签中。
代码实现
以下代码演示了如何实现此方法:
$doc = new DOMDocument; $doc->loadXML($str); $xp = new DOMXPath($doc); // Search elements containing the search text $r = $xp->query('//*[contains(., "'.$search.'")]/*[FALSE = contains(., "'.$search.'")]/..', $anchor); // Process search results foreach($r as $i => $node) { // Extract search text nodes and create suitable nodes if necessary $range = new TextRange($xp->query('.//child::text()', $node)); $ranges = array(); while(FALSE !== $start = strpos($range, $search)) { $base = $range->split($start); $range = $base->split(strlen($search)); $ranges[] = $base; }; // Wrap matching text nodes foreach($ranges as $range) { foreach($range->getNodes() as $node) { $span = $doc->createElement('span'); $span->setAttribute('class', 'search_hightlight'); $node = $node->parentNode->replaceChild($span, $node); $span->appendChild($node); } } }
此代码搜索包含搜索文本的元素,忽略不包含它的任何子元素。搜索区域表示为 TextRange 对象,允许在匹配文本周围插入跨度标签。结果是修改后的 XML 字符串,其中突出显示搜索结果,而不会破坏 HTML 结构。
以上是如何在不破坏结构的情况下突出显示 HTML 中的搜索结果?的详细内容。更多信息请关注PHP中文网其他相关文章!