今天在文章管理过程中,突然发现部分文章遇到HTML标签不完整或丢失的情况,这可能导致页面显示异常。为此,我写了一个简单高效的PHP函数,能够自动检测并修复未闭合的HTML标签。
上代码:
function fixHtmlTags($html) {
if (empty(trim($html))) return $html;
$stack = [];
$selfClosingTags = ['img', 'br', 'hr', 'input', 'meta', 'link', 'area', 'base', 'col', 'embed'];
// 修复标签内部属性未闭合的情况(如 <p class="a>)
$html = preg_replace_callback('/<([a-z][a-z0-9]*)([^>]*)$/i', function($matches) use ($selfClosingTags) {
$tagName = strtolower($matches[1]);
$attributes = $matches[2];
// 检查属性中是否有未闭合的引号
if (preg_match('/=("[^"]*$|\'[^\']*$)/', $attributes)) {
// 修复未闭合的属性值
$attributes = rtrim($attributes) . '"';
}
// 对于自闭合标签使用 />,其他使用 >
if (in_array($tagName, $selfClosingTags)) {
return "<$tagName$attributes />";
} else {
return "<$tagName$attributes>";
}
}, $html);
// 修复未写完的标签(如 <p class="a)
if (preg_match('/<([a-z][a-z0-9]*)(?:\s+[^>]*)?$/i', $html, $matches)) {
$tagName = strtolower($matches[1]);
$html .= in_array($tagName, $selfClosingTags) ? ' />' : '>';
}
// 匹配所有HTML标签
preg_match_all('/<(\/?)([a-z][a-z0-9]*)(?:[^>]*)?>/i', $html, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$isClosing = ($match[1] === '/');
$tagName = strtolower($match[2]);
if (in_array($tagName, $selfClosingTags)) continue;
if ($isClosing) {
if (!empty($stack) && end($stack) === $tagName) {
array_pop($stack);
}
} else {
$stack[] = $tagName;
}
}
// 为栈中剩余的未闭合标签添加闭合标签
$result = $html;
while (!empty($stack)) {
$tag = array_pop($stack);
$result .= "</$tag>";
}
return $result;
}
评论
发表评论: