正则表达式-如何简单匹配HTML中a标签的href

3,420 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情

前言

通过爬虫将整个网页提取出来,然后获取的其中 a 标签中 href 属性的值,也就是获取所有链接。

但是,所有链接的格式并不一致,如果在正则表达式中枚举出所有链接类型,将会有两个很明显的缺点:

  1. 正则表达式过于繁琐冗长,不利于以后的扩展和维护;
  2. 要将所有链接类型枚举出来,工作量大,还容易遗漏与出错。

那有没有简单点的方法呢?

基本思路

既然正面匹配不行,那就换一种思路,不直接去匹配链接的类型。

直接先去匹配链接所在的起始位置,通过 .* 匹配到的位置后面的字符就可以了。

但是,如果不给终止的位置,会直接匹配到一些多余字符,所以还得加上一个终止的标制才行。

实现

首先,目标是 a 标签里面的链接,换句话说,目标在 a 标签里面。那么,直接通过预查找到 a 里面:

const reg = /(?<=<a)/

微信截图_20220822215943.png

但这位置还不能满足要求,目标在 href=" 后面,还需要更近一步,所以预查匹配可以继续加上 href=",进一步获取到准确的位置:

const reg = /(?<=<a.*href=")/

微信截图_20220822220246.png

注意:在 ahref=" 之间加上 .*,是因为不知道它们中间会存在什么字符,但是至少也是有一个空格存在,所有使用 .* 进行匹配,又因为在后面写上了 href=",所以 .* 会匹配除了 href=" 之外的字符。

现在,已经到达了目标位置,接下来就是匹配所需要的链接,根据上面的思路,直接使用 .* 进行匹配即可,不用再考虑链接的格式。

但这样,但这样容易匹配到多余的字符,所以再加上一个终止的位置,链接一般以双引号 " 结尾,加上一个(?=") 即可,最终表达式如下:

const reg = /(?<=<a.*href=").*(?=")/

微信截图_20220822221615.png

修改

经过评论区掘有提醒,当a标签上存在其他属性时,会影响获取结果,因此,按照上面的思路,可以再加上限制,限制匹配的字符为非",修改后如下:

const reg = /(?<=<a.*href=")([^"]*)(?=")/g