如何在PHP中移除变量内的<sup>标签及指定CSS类
PHP移除指定HTML标签与CSS类实现方案
完全可以通过PHP原生能力实现该需求,不要用正则直接处理HTML,正则对属性顺序变化、标签嵌套的场景容错率极低,推荐使用PHP内置的DOMDocument+DOMXPath解析处理,稳定性更强。
完整实现代码
以下代码默认行为:
- 移除所有
<sup>标签及其内部包裹的内容 - 移除所有元素上的
navigation-only、noprint、wikidata-linkback三个CSS类,类移除后如果元素class属性为空则直接删除该属性
// 初始化DOM解析器,屏蔽不规范HTML的报错 $dom = new DOMDocument(); libxml_use_internal_errors(true); // 加载HTML内容,前置编码声明避免UTF-8内容乱码 $dom->loadHTML('<?xml encoding="utf-8" ?>' . $matches[0], LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); libxml_clear_errors(); $xpath = new DOMXPath($dom); // 处理1:删除所有<sup>标签及内部内容 $supNodes = $xpath->query('//sup'); foreach ($supNodes as $supNode) { $supNode->parentNode->removeChild($supNode); // 如果你需要保留<sup>内部的文本、仅删除标签本身,注释掉上面的removeChild行,放开下面这段代码即可 // while ($supNode->firstChild) { // $supNode->parentNode->insertBefore($supNode->firstChild, $supNode); // } // $supNode->parentNode->removeChild($supNode); } // 处理2:移除指定CSS类 $removeClasses = ['navigation-only', 'noprint', 'wikidata-linkback']; $allClassNodes = $xpath->query('//*[@class]'); foreach ($allClassNodes as $node) { $rawClass = trim($node->getAttribute('class')); $classArr = preg_split('/\s+/', $rawClass); // 过滤掉需要删除的类 $classArr = array_filter($classArr, function($className) use ($removeClasses) { return !in_array($className, $removeClasses); }); // 剩余类为空则删除class属性,否则回写处理后的类名 if (empty($classArr)) { $node->removeAttribute('class'); } else { $node->setAttribute('class', implode(' ', $classArr)); } } // 取出处理完成的HTML,移除前置的编码声明 $result = str_replace('<?xml encoding="utf-8" ?>', '', $dom->saveHTML());
需求调整:直接删除带指定类的整个元素
如果你不需要保留带navigation-only、noprint wikidata-linkback类的元素,要把整个元素连带内容一起删掉,可以把上面「处理2」的代码替换为以下内容:
// XPath匹配对应class的元素,做精确匹配避免类名部分命中 $targetSelectors = [ '//*[contains(concat(" ", normalize-space(@class), " "), " navigation-only ")]', '//*[contains(concat(" ", normalize-space(@class), " "), " noprint ")][contains(concat(" ", normalize-space(@class), " "), " wikidata-linkback ")]' ]; foreach ($targetSelectors as $selector) { $nodes = $xpath->query($selector); foreach ($nodes as $node) { $node->parentNode->removeChild($node); } }
内容的提问来源于stack exchange,提问作者user7962781
相关产品推荐
相关产品推荐

