首先,请注意空的 HTML 元素,根据定义,不是嵌套的。
更新:下面的解决方案现在递归地应用空元素正则表达式来删除“嵌套空元素”结构,例如:(<p><strong></strong></p>
受以下注意事项的约束)。
简单版:
<>
对于没有包含有趣内容的开始标记属性的 HTML(以(未经测试)VB.NET 片段的形式),这非常有效(请参阅下面的警告) :
Dim RegexObj As New Regex("<(\w+)\b[^>]*>\s*</\1\s*>")
Do While RegexObj.IsMatch(html)
html = RegexObj.Replace(html, "")
Loop
增强版
<(\w+)\b(?:\s+[\w\-.:]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[\w\-.:]+))?)*\s*/?>\s*</\1\s*>
这是 VB.NET 中未注释的增强版本(未经测试):
Dim RegexObj As New Regex("<(\w+)\b(?:\s+[\w\-.:]+(?:\s*=\s*(?:""[^""]*""|'[^']*'|[\w\-.:]+))?)*\s*/?>\s*</\1\s*>")
Do While RegexObj.IsMatch(html)
html = RegexObj.Replace(html, "")
Loop
这个更复杂的正则表达式正确匹配一个有效的空 HTML 4.01 元素,即使它的属性值中有尖括号(再次受制于下面的警告)。换句话说,这个正则表达式正确处理所有被引用(可以有<>
)、未引用(不能)和空的开始标记属性值。这是一个完全注释(和测试)的 PHP 版本:
function strip_empty_tags($text) {
// Match empty elements (attribute values may have angle brackets).
$re = '%
# Regex to match an empty HTML 4.01 Transitional element.
< # Opening tag opening "<" delimiter.
(\w+)\b # $1 Tag name.
(?: # Non-capture group for optional attribute(s).
\s+ # Attributes must be separated by whitespace.
[\w\-.:]+ # Attribute name is required for attr=value pair.
(?: # Non-capture group for optional attribute value.
\s*=\s* # Name and value separated by "=" and optional ws.
(?: # Non-capture group for attrib value alternatives.
"[^"]*" # Double quoted string.
| \'[^\']*\' # Single quoted string.
| [\w\-.:]+ # Non-quoted attrib value can be A-Z0-9-._:
) # End of attribute value alternatives.
)? # Attribute value is optional.
)* # Allow zero or more attribute=value pairs
\s* # Whitespace is allowed before closing delimiter.
> # Opening tag closing ">" delimiter.
\s* # Content is zero or more whitespace.
</\1\s*> # Element closing tag.
%x';
while (preg_match($re, $text)) {
// Recursively remove innermost empty elements.
$text = preg_replace($re, '', $text);
}
}
注意事项:此函数不解析 HTML。它只是匹配并删除与有效的空 HTML 4.01 元素相对应的任何文本模式序列(根据定义,它不是嵌套的)。请注意,这也会错误地匹配并删除可能出现在正常 HTML 标记之外的相同文本模式,例如在 SCRIPT 和 STYLE 标记和 HTML 注释以及其他开始标记的属性中。此正则表达式不适用于短标签。对于任何想要给这个答案自动投反对票的 bobenc 粉丝,请告诉我一个有效的 HTML 4.01 空元素,这个正则表达式无法正确匹配。这个正则表达式遵循 W3C 规范并且确实有效。
更新:这个正则表达式解决方案也不起作用(并且会错误地删除有效的标记),如果你做了一些非常不可能(但完全有效)的事情,如下所示:
<div att="<p att='">stuff</div><div att="'></p>'">stuff</div>
概括:
再三考虑,只需使用 HTML 解析器!