PHP使用DomDocument如何修改代码以移除括号及内部包含的内容
问题说明
- 实现目标:通过
DomDocument搭配处理逻辑,移除页面中所有class包含语言标识类名的span标签,这类标签对应括号包裹的语言标记,例如(d)、(en)。 - 现存异常:现有代码可正常匹配删除目标span,但仅能移除括号内的语言字符(如d、en),无法移除包裹内容的括号本身,最终会残留空的
()。
原有实现代码
libxml_use_internal_errors(true); $parser = new DOMDocument(); $parser->loadHTMLFile("https://fr.wikipedia.org/wiki/Mark_Zuckerberg"); $get_span_tags = $parser->getElementsByTagName("span"); foreach ($get_span_tags as $get_span_tag) { if (stripos($get_span_tag->getAttribute('class'), "indicateur-langue") !== false) { $get_infoxbox_span = $parser->saveHTML($get_span_tag); $wikipediaInfoboxTable = str_ireplace($get_infoxbox_span, "", $wikipediaInfoboxTable); } } echo $wikipediaInfoboxTable;
问题原因
残留空括号的核心原因是:目标页面的语言标记DOM结构为文本节点( + span.indicateur-langue + 文本节点),左右括号本身是独立于span的相邻文本节点,不属于span标签的内部内容。原有逻辑仅删除了span节点本身,没有处理前后的括号文本,自然会残留空括号。
另外用字符串替换处理解析后的HTML本身稳定性很差,只要HTML结构有微小变动就会匹配失败。
修正方案
直接在DOM层面操作节点,匹配到目标span后,同步删除其前后紧邻的括号文本节点,最后删除span本身即可。注意遍历节点时不要边遍历边删除,避免动态节点列表指针偏移导致漏删。
修正后代码:
libxml_use_internal_errors(true); $parser = new DOMDocument(); $parser->loadHTMLFile("https://fr.wikipedia.org/wiki/Mark_Zuckerberg"); $get_span_tags = $parser->getElementsByTagName("span"); // 先收集所有待删除的span节点,避免遍历过程中节点列表变动 $targetSpans = []; foreach ($get_span_tags as $span) { if (stripos($span->getAttribute('class'), "indicateur-langue") !== false) { $targetSpans[] = $span; } } foreach ($targetSpans as $spanNode) { // 删除span前紧邻的左括号文本节点 $prev = $spanNode->previousSibling; if ($prev && $prev->nodeType === XML_TEXT_NODE && trim($prev->nodeValue) === '(') { $prev->parentNode->removeChild($prev); } // 删除span后紧邻的右括号文本节点 $next = $spanNode->nextSibling; if ($next && $next->nodeType === XML_TEXT_NODE && trim($next->nodeValue) === ')') { $next->parentNode->removeChild($next); } // 删除语言标识span本身 $spanNode->parentNode->removeChild($spanNode); } // 直接从DOM对象导出处理后的HTML即可,无需额外字符串替换 $wikipediaInfoboxTable = $parser->saveHTML(); echo $wikipediaInfoboxTable;
内容的提问来源于stack exchange,提问作者user7962781
相关产品推荐
相关产品推荐

