有人有匹配未闭合的HTML标签的正则表达式吗?例如,该正则表达式将匹配<b>
和第二个<i>
,但不会匹配第一个<i>
或第一个的结束标签</i>
:
<i><b>test<i>ing</i>
这个需要使用正则表达式吗?可能需要一些递归的编程处理吗?
您可以使用正则表达式来识别所有的HTML开始/结束元素,然后使用堆栈枚举,推入新元素并弹出关闭标签。在C#中尝试一下:
public static bool ValidateHtmlTags(string html)
{
string expr = "(<([a-zA-Z]+)\\b[^>]*>)|(</([a-zA-Z]+) *>)";
Regex regex = new Regex(expr, RegexOptions.IgnoreCase);
var stack = new Stack<Tuple<string, string>>();
var result = new StringBuilder();
bool valid = true;
foreach (Match match in regex.Matches(html))
{
string element = match.Value;
string beginTag = match.Groups[2].Value;
string endTag = match.Groups[4].Value;
if (beginTag == "")
{
string previousTag = stack.Peek().Item1;
if (previousTag == endTag)
stack.Pop();
else
{
valid = false;
break;
}
}
else if (!element.EndsWith("/>"))
{
// Write more informative message here if desired
string message = string.Format("Char({0})", match.Index);
stack.Push(new Tuple<string, string>(beginTag, message));
}
}
if (stack.Count > 0)
valid = false;
// Alternative return stack.Peek().Item2 for more informative message
return valid;
}
<[^/]+$
,它匹配一个"<
",然后是任何不是"/
"的字符。正如@Pesto所说,HTML并不规则,您需要构建HTML语法规则,并递归地应用它们。
如果您想通过编程方式修复HTML,我曾经使用过一个名为html tidy的组件,并取得了相当大的成功。对于大多数语言(COM+,Dotnet,PHP等),都有该组件的版本。
如果您只需要手动修复它,我建议使用一个好的IDE。Visual Studio 2008做得很不错,最新版本的Dreamweaver也不错。
不,这对于正则表达式来说太复杂了。你的问题相当于测试括号的正确使用的算术表达式,这需要至少一个下推自动机才能成功。
在你的情况下,你应该将HTML代码分割成开放标签、关闭标签和文本节点(例如使用正则表达式)。将结果存储在列表中。然后,您可以遍历节点列表并将每个开放标签推送到堆栈上。如果在节点列表中遇到一个关闭标签,则必须检查最顶部的堆栈条目是否是相同类型的开放标签。否则,您找到了您要查找的HTML语法错误。
for (Question q : questionsTagged("regex", "html")) { q.addAnswer(new Answer("HTML不规则,所以正则表达式几乎从来不是一个好选择。")); }
- Michael Myers