PHP正则替换含obfuscate类标签内的<a>标签
需求说明
现有存储在PHP变量中的HTML代码,需替换所有位于带有obfuscate类的父级标签内的<a>标签,具体规则如下:
- 将
<a>标签转为<span>标签 - 继承原
<a>标签的所有属性 - 给新
<span>标签添加akn-obf-link类 - 把原
<a>的href值经base64_encode()处理后存入data-o属性 - 根据原
<a>是否包含target="_BLANK",给data-b属性设置为1(包含)或0(不包含)
注:已有针对<a>自身带obfuscate类的实现代码,现需修改为作用于父级标签带该类的场景。
转换示例
原HTML代码
<div class="obfuscate foobar"><strong><a href="https://example.com" class="randomclass" target="_BLANK">test</a></strong></div>
转换后代码
<div class="obfuscate foobar"><strong><span class="akn-obf-link randomclass" data-o="aHR0cHM6Ly9leGFtcGxlLmNvbQ==" data-b="1">test</span></strong></div>
PHP实现方案
使用PHP的DOMDocument+DOMXPath精准处理HTML结构,避免正则解析HTML的兼容性问题,代码如下:
<?php // 原始HTML变量 $html = '<div class="obfuscate foobar"><strong><a href="https://example.com" class="randomclass" target="_BLANK">test</a></strong></div>'; // 初始化DOM并加载HTML $dom = new DOMDocument(); libxml_use_internal_errors(true); // 屏蔽HTML格式警告 $dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8')); libxml_clear_errors(); // XPath定位目标a标签:所有被带obfuscate类的父元素包含的a标签 $xpath = new DOMXPath($dom); $targetLinks = $xpath->query('//*[contains(concat(" ", normalize-space(@class), " "), " obfuscate ")]//a'); foreach ($targetLinks as $link) { // 创建新span标签 $span = $dom->createElement('span'); // 复制原a标签的属性(跳过href和target) foreach ($link->attributes as $attr) { if ($attr->name !== 'href' && $attr->name !== 'target') { $span->setAttribute($attr->name, $attr->value); } } // 添加akn-obf-link类 $existingClass = $span->getAttribute('class'); $span->setAttribute('class', trim("$existingClass akn-obf-link")); // 设置data-o属性:base64编码原href $span->setAttribute('data-o', base64_encode($link->getAttribute('href'))); // 设置data-b属性:判断是否有target="_BLANK" $span->setAttribute('data-b', strtolower($link->getAttribute('target')) === '_blank' ? '1' : '0'); // 复制原a标签的子内容 foreach ($link->childNodes as $child) { $span->appendChild($child->cloneNode(true)); } // 替换原a标签为span $link->parentNode->replaceChild($span, $link); } // 清理DOM自动添加的html/body标签,输出结果 $processedHtml = preg_replace('~<(?:!DOCTYPE|/?(?:html|body))[^>]*>\s*~i', '', $dom->saveHTML()); echo $processedHtml; ?>
代码说明
- XPath表达式
//*[contains(concat(" ", normalize-space(@class), " "), " obfuscate ")]//a可精准匹配父级带obfuscate类的<a>标签,避免误匹配类似obfuscatexxx的无关类名 - 全程使用DOM操作处理HTML结构,兼容各种嵌套场景
- 保留原
<a>标签除href、target外的所有属性,确保样式和其他特性不丢失
内容的提问来源于stack exchange,提问作者rAthus
相关产品推荐
相关产品推荐

