如何使用preg_replace移除表格元素中的所有height标签与属性?
问题
用户从Excel/Word复制粘贴表格到系统后,table、tr、td标签会带有height属性或style内的height规则,导致PHP API生成格式化报告时出现异常。需要实现:
- 仅移除
table、tr、td标签内的height相关内容 - 若
style属性仅包含height规则,移除整个style属性;若还有其他规则,仅移除height部分
示例输入:
<table style="height:126px;" width="243"> <tbody> <tr style="height: 18px;"> <td style="width: 38.5px; height: 18px;">ABC</td> <td style="width: 41.5469px; height: 18px;">123</td> <td style="width: 50.6562px; height: 18px;">DEF;</td> <td style="width: 99.2969px; height: 18px;">456</td> </tr> <tr style="height:18px;"> <td style="width: 38.5px; height: 18px;">GHI</td> <td style="width: 41.5469px; height: 18px;">789</td> <td style="width: 50.6562px; height: 18px;">JKL</td> <td style="width: 99.2969px; height: 18px;">012</td> </tr> <tr style="height:18px;"> <td style="width: 38.5px; height: 18px;">MNO</td> <td style="width: 41.5469px; height: 18px;">345</td> <td style="width: 50.6562px; height: 18px;">PQR</td> <td style="width: 99.2969px; height: 18px;">678</td> </tr> </tbody> </table>
期望输出:
<table width="243"> <tbody> <tr> <td style="width: 38.5px;">ABC</td> <td style="width: 41.5469px;">123</td> <td style="width: 50.6562px;">DEF;</td> <td style="width: 99.2969px;">456</td> </tr> <tr> <td style="width: 38.5px;">GHI</td> <td style="width: 41.5469px;">789</td> <td style="width: 50.6562px;">JKL</td> <td style="width: 99.2969px;">012</td> </tr> <tr> <td style="width: 38.5px;">MNO</td> <td style="width: 41.5469px;">345</td> <td style="width: 50.6562px;">PQR</td> <td style="width: 99.2969px;">678</td> </tr> </tbody> </table>
解决方案
方法一:使用DOM解析器(推荐)
正则处理HTML易受格式不规范影响,DOM解析能稳定应对各种场景,是更可靠的选择。PHP代码示例:
$html = '<table style="height:126px;" width="243">...</table>'; // 替换为你的输入HTML $dom = new DOMDocument(); libxml_use_internal_errors(true); // 忽略HTML解析时的非致命错误 $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // 避免自动添加<html>/<body>标签 libxml_clear_errors(); // 遍历目标标签处理 $targetTags = ['table', 'tr', 'td']; foreach ($targetTags as $tag) { $elements = $dom->getElementsByTagName($tag); // 倒序遍历避免索引混乱 for ($i = $elements->length - 1; $i >= 0; $i--) { $element = $elements->item($i); // 移除独立的height属性 if ($element->hasAttribute('height')) { $element->removeAttribute('height'); } // 处理style属性中的height规则 if ($element->hasAttribute('style')) { $styleContent = $element->getAttribute('style'); // 移除所有height相关规则 $cleanedStyle = preg_replace('/\s*height:\s*[^;]+;?\s*/', '', $styleContent); $cleanedStyle = trim($cleanedStyle, '; '); if (empty($cleanedStyle)) { // 清理后style为空,移除整个属性 $element->removeAttribute('style'); } else { $element->setAttribute('style', $cleanedStyle); } } } } $cleanHtml = $dom->saveHTML(); echo $cleanHtml;
方法二:使用preg_replace(仅适用于格式规范的HTML)
若你的HTML格式严格统一(无换行标签、属性引号统一),可以用正则快速处理:
$html = '<table style="height:126px;" width="243">...</table>'; // 替换为你的输入HTML // 第一步:移除table/tr/td内独立的height属性 $html = preg_replace('/(<(table|tr|td)[^>]*)\s+height="[^"]+"([^>]*>)/i', '$1$3', $html); // 第二步:处理style属性中的height规则 $html = preg_replace('/(<(table|tr|td)[^>]*style=")([^"]*)\s*height:\s*[^;]+;?\s*([^"]*)"/i', function($matches) { $combinedStyle = trim($matches[3] . $matches[4], '; '); if (empty($combinedStyle)) { // 清理后style为空,移除整个属性 return str_replace('style=""', '', $matches[0]); } else { return $matches[1] . $combinedStyle . '"'; } }, $html); echo $html;
说明
- DOM解析方法适配性强,能处理单引号属性、跨行标签、无引号属性等不规范场景
- 正则方法仅适合格式高度统一的HTML,遇到复杂结构(如style内含特殊字符)可能失效
内容的提问来源于stack exchange,提问作者B4THC4T
相关产品推荐
相关产品推荐

