我想到的不优雅但最快的解决方案是:
然后
理想情况下,您可以使用合法的解析器解析有效的 HTML,然后使用正则表达式仅将搜索词替换为单词边界(这样
BLASPHEMY
就不会意外损坏)。
我什至会放入一个正则表达式条件表达式来用找到的术语修剪前导或尾随空格(但它不会替换两端的空格 - 这会很糟糕)。
代码:(演示)
$html = <<<HTML
<p>Ple ple ple BLA xo xo xo <span class="tooltip-content"><span class="tooltip-text">uuu BLA pla</span></span> he BLAZE he BLA he ha ha ha.</p>
HTML;
$find = 'BLA';
$doc = new DOMDocument();
$doc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($doc);
foreach ($xpath->query('//text()[not(ancestor::span[contains(@class, "tooltip-content")])]') as $node) {
$node->nodeValue = preg_replace("/(\s)?\b$find\b(?(1)|\s*)/", '', $node->nodeValue);
}
echo $doc->saveHTML();
输出:
<p>Ple ple ple xo xo xo <span class="tooltip-content"><span class="tooltip-text">uuu BLA pla</span></span> he BLAZE he he ha ha ha.</p>
构建一个纯正则表达式解决方案需要太多的卷积来适应嵌套标签、不同的引用、可选属性、不在开始标签内的文本以及其他类似的问题。 使用 XPath 排除属于
tooltip-content
类标签的子标签的文本节点要干净得多。