最蛋疼的HTML标签正则表达式
普通的HTML标签的正则表达式为
@"<(!|/)?(.|\n)*?>"
上面的第二个问号是贪婪模式,找到一个>即停止。
但是如果告诉你有如下一个html标签的实例,上面的这个就不够用了
<a onclick="s_objectid='top picks 3 title'" href="?sid=18394376&nid=1017&title=have-you-seen-this-mythbusters-bust-house" onmouseover="tip(' zany experiments testing scientific theories in real world settings have earned the tv show &quot;mythbusters&quot; a devoted following, but a stunt gone wrong met with an unhappy audience when an errant cannonball went shooting through a california family\'s bedroom. <div style="font-size: 10px; color: #666">dec 7th - 2:14pm</div>', title,'have you seen this? \'mythbusters\' bust house')" onmouseout="untip()" >
这不是我杜撰的,是我爬网页时找到的最变态的锚标签,其中出现了<div>和</div>。
如果用最开头的那个就无法匹配了,会直接从第一个“>”那里截断。
html标签有以下几个特别的特点:
1. 如果有属性,那么它之前肯定有空格。
2. 收尖括号的前面一定是双引号,或者双引号加上少许空格
根据这两个特点,我写了一个最蛋疼的html标签的正则表达式如下:
@"<(!|/)?\w+( ((.|\n)*?"")?)? *>"
第二个问号是指贪婪模式找到收尖括号即停止,
第三个问号是指如果出现属性,则一定是以双引号结尾的,
第四个问号是指有可能不出现属性。
第一个空格是指第一个属性的前面有一个空格,
第二个空格指的是最后一个属性的后面可能会有空格。
这里面出现了两个双引号的并列,那就是双引号在有@符号里面的写法,并非\",而要写成""。
这个标签能完美匹配上面的那个例子,以及我爬网页时出现的其它各种情况。
个人拙见,欢迎拍砖。
一楼的童鞋的建议很重要,根据他的建议,我写了一个函数,查看每一个char,以获取下一个Tag的字符串
public static string GetNextTag(string html, ref int start)
{
if (start >= html.Length)
return null;
int tagStartIndex = html.IndexOf('<', start);
if (tagStartIndex < 0)
return null;
int rightBracketCount = 0;
int leftBracketCount = 1;
int currentIndex = tagStartIndex + 1;
while (currentIndex < html.Length && leftBracketCount != rightBracketCount)
{
if (html[currentIndex] == '<')
leftBracketCount++;
else if (html[currentIndex] == '>')
rightBracketCount++;
currentIndex++;
}
if (leftBracketCount == rightBracketCount)
{
string tagString = html.Substring(tagStartIndex, currentIndex - tagStartIndex);
start = currentIndex;
return tagString;
}
else
return null;
}