C#正则表达式匹配html a标签的href属性

   并不是很难,但是整理一个明确而清晰的思路是必要的

需要:一个在线的正则表达式网站:https://regexr.com/

   一点正则表达式知识

下面是一个输入样例(以END结束,注意我稍微修改了这句a href = '/forum lll' 原来是a href = '/forum'),为什么改之后会说

<!DOCTYPE html>
<html>
<head>
  <title>Hyperlinks</title>
  <link href="theme.css" rel="stylesheet" />
</head>
<body>
<ul><li><a   href="/"  id="home">Home</a></li><li><a
 class="selected" href=/courses>Courses</a>
</li><li><a href = 
'/forum lll'>Forum</a></li><li><a class="href"
οnclick="go()" href= "#">Forum</a></li>
<li><a id="js" href =
"javascript:alert('hi yo')" class="new">click</a></li>
<li><a id='nakov' href =
http://www.nakov.com class='new'>nak</a></li></ul>
<a href="#empty"></a>
<a id="href">href='fake'<img src='http://abv.bg/i.gif' 
alt='abv'/></a><a href="#">&lt;a href='hello'&gt;</a>
<!-- This code is commented:
  <a href="#commented">commentex hyperlink</a> -->
</body>
END

下面是对于输入的结果

我们可以看到输入样例中的href属性有以下几种形式:

  1. "xxxx",以"开始,"结束,中间可以出现任意除了"的字符(包括空格和单引号');
  2. 没有确定的开始符号,但是必然以空格或者>结束
  3. 'xxxx',与"xxx"类似,不再赘述。

因此我们可以把href=后面的正则表达式写出来。

(("[^"]*")|(\'[^\']*\')|[^>^\s]+))

注意:这个正则表达式表示先看是不是"xxx"的形式,再看是不是'xxx'的形式,如果不是,说明是形式2,此时直接一路直接匹配到结束符>或空格。

请注意这个顺序,前两个可以随意改变,但是第三个是在前两个都不行的情况下才匹配,所以第三个匹配项不能直接跑到第一个或第二个位置,否则会出错,假如改成这样:

(("[^"]*")|[^>^\s]+|(\'[^\']*\'))

那么'xxx'的项会在第二部分被匹配,那么如果'xxx'内含有空格,那个匹配到空格处停止,就会缺少字符。

如果想要[^>^\s]+ 放在中间或是第一个,需要这样:

(([^'^">^\s]+)|("[^"]*")|(\'[^\']*\'))

即不匹配包含"和'的项,注意这个和第一次写的正则表达式是有区别的,即这种情况下,对于形式2,这次的正则表达式不能在形式2的中间出现双引号和单引号,而之前是可以的,见下图

对于第一个正则表达式:

(("[^"]*")|(\'[^\']*\')|[^>^\s]+))

对于第三个正则表达式:

(([^'^">^\s]+)|("[^"]*")|(\'[^\']*\'))

注意最后一行的不同

当然在这个给出的样例和真正的html文本中,上述情况是没有的,所以这两个都可以

下面解释一个<a 和href之间的字符如何表达。

可以从上面的图片中看到是这样的:

<a([^\>]+|\s+)href

即在a和href之间可以出现多个空格和非>的字符,因为可能出现a标签中没有href的情况,此时会匹配到>末尾结束,不符合条件。

href 和=之间可以有0或多个空格,=和属性值之间同样如此。

所以有整个的正则表达式如下:(注意我在这个字符串前面使用了@,所以""表示")

string pattern = @"\<a([^\>]+|\s+)href\s*=\s*((""[^""]*"")|(\'[^\']*\')|[^>^\s]+)";

得到MatchCollection之后,再得到最后一部分,再对开头结尾的双引号和单引号处理一下,就能得到之前图片中的结果。

注意我稍微修改了输入文件中这句a href = '/forum lll' 原来是a href = '/forum',是因为我最开始根本没看到有单引号的项,我只做了形式1和2,但是对于没改之前的输入文件是可以得到正确结果的,因为'/forum' 满足形式2,以空格结束,但是我想还是用正规的思想进行一遍。

然后我这个思路是在做完之后进行整理的,也就是从最关键的地方说起到底怎么做,我们实际在做的过程中,完全不必先这样,可以先只是匹配完整的a标签(<a xxxxx>),然后再观察href的特性,再去解决,慢慢地在网站上更改,直到逻辑和结果都是正确的

发布了32 篇原创文章 · 获赞 5 · 访问量 4663

猜你喜欢

转载自blog.csdn.net/qq_38941327/article/details/89278425