使用正则表达式匹配HTML标签出现了问题

今天有这样一个需求:需要匹配好多个HTML文件,从中找出所有的标题文字。

正则表达式

这本是一个简单的需求,只需要使用正则表达式进行匹配即可。下列是我们当时所使用的表达式:

<[hH][1-6]>.*?<\/[hH][1-6]>

测试

我们编写了测试数据,并获取到测试结果:

在这里插入图片描述

这是我们的测试数据,获取到的测试结果为:

在这里插入图片描述

可以看到,这其实没有问题。但是,我们的同学在实操的过程中,出现了一些失误,就是:他不小心打开了HTML文件,导致操作出现了一些问题。简单来说就是:因为勿删或其它原因,使得HTML标签匹配不完整,该正则表达式将无效标签(如<h2></h3>这样的)也匹配到了。

怎么解决呢?

反向引用

如,你想把连续重复复现两次的单词打印出来,就可以使用反向引用。

反向引用允许正则表达式模式引用之前匹配的结果。基本原理是:反向引用在捕获组匹配成功时,会将子表达式匹配到的内容,保存到内存中一个以数字编号的组里,可以简单的认为是对一个局部变量进行了赋值,这时就可以通过反向引用方式,引用这个局部变量的值。捕获组在匹配成功之前,它的内容可以是不确定的,一旦匹配成功,它的内容就确定了,反向引用的内容也就是确定的了

反向匹配的符号是:\n,例如:\1表示匹配模式中所使用的第一个子表达式,\2匹配第二个子表达式,\3匹配第三个,以此类推。

匹配重复字符

如:匹配这段文字repeated, and and they里连续重复两次的单词,可以使用正则表达式:[ ](\w+)[ ]\1

注意,\w+是出现在括号里,所以它是一个子表达式,该子表达式对模式进行分组,将其标识出来以备候用。模式最后一部分是\1,这是对前面那个子表达式的反向引用,\1匹配的内容与第一个分组匹配的内容一样。如果(\w+)匹配的单词是of,那么\1也匹配 of。

匹配HTML标签

这下,针对无效标签,就可以使用反向匹配来解决了。表达式为:

<([hH][1-6])>.*?<\/\1>

我们写了这样的一组测试数据:

let html = `<div>
        <h1>将进酒</h1>
        This is the Qiangjinjiu full text:<br/>
        <h2>君不见黄河之水天上来,奔流到海不复回。</h2>
        the next
        <h3>君不见高堂明镜悲白发,朝如青丝暮成雪。</h1>
        <h2>人生得意须尽欢,莫使金樽空对月。</h3>
        <h2>天生我材必有用,千金散尽还复来。</h3>
        <h2>烹羊宰牛且为乐,会须一饮三百杯。</h2>
            岑夫子,丹丘生,将进酒,杯莫停。
            与君歌一曲,请君为我倾耳听。
            钟鼓馔玉不足贵,但愿长醉不愿醒。
            古来圣贤皆寂寞,惟有饮者留其名。
            陈王昔时宴平乐,斗酒十千恣欢谑。
            主人何为言少钱,径须沽取对君酌。
            五花马、千金裘,呼儿将出换美酒,与尔同销万古愁。
        The End.
    </div>`

    let reg = /<([hH][1-6])>.*?<\/\1>/g
    console.log(html.match(reg))

结果是:

<h1>将进酒</h1>
<h2>君不见黄河之水天上来,奔流到海不复回。</h2>
<h2>烹羊宰牛且为乐,会须一饮三百杯。</h2>

我们还使用了多组测试数据,这种写法的表达式都不会出错,匹配HTML标签的问题完美解决。

总结

对于使用正则表达式匹配HTML标签,我从来没有想过会有这样的问题出现。本以为是非常简单的一件事情,在这个问题上还是处理了很久。好在我们最后发现了错误的原因和错误本身、并且找到了使用反向引用这样第一个写法,完美解决了问题。

在解决这个问题的过程中,反正引用真的特别重要,要是没有反向引用,我们可能根本没法解决问题或需要花费更大的力气来解决这个问题。

  • 16
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值