平衡正则 html,正则表达式-利用平衡组匹配html

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

从下面的HTML代码片段中匹配 到 span#test 标签内容1

2

3

4

5

6

7

8

9

hi~

虫虫

早上好

首先要找到 标签 和 标签 ,如果这两个不会,后面不用看了……补基础吧~~1

2

3

4//起始

]*id="test"[^>]*>

//结束

我们会发现代码中夹杂着多个HTML标签,em还好,因为正则里面写死了是 span, 所以它是可以直接忽略掉的, 但是多余的 会造成干扰。那么如果是在程序中,我们是怎么处理的呢? 可以使用计数器(或者说是stack结构,但是我们只需要关心里面的元素个数,所以使用计数器就行了)。从id=”test” 后面的开始处理,遇到 计数+1 ,遇到 时,如果计数>0则-1否则 就匹配到了找到#test 的span 后开始,(如果找不到这个id的span,其实可以直接结束匹配了)

var c = 0; // 初始栈

遇到 ,入栈,栈内标签数量: c=c+1=1;

遇到 ,入栈: c=c+1=2;

遇到虫虫后面的 (关闭span3) , 因为 c>0 所以c=c-1=1;

下一个 (关闭span1), 因为 c>0 所以所以c=c-1=0;

遇到 c=c+1 = 1

下一个 (关闭span3), 因为 c>0 所以所以c=c-1=0;

下一个 (关闭test),因为此时 c==0 , 所以匹配到这里结束了。

有同学会纠结标签怎么办?em并不是我们要查找的标签名称,直接当普通字符串忽略掉就是了……

根据这个思路 ,我们可以使用正则表达式中平衡组的概念,首先将span定义到一个分组中,那么查找 #test 的开始标签就可以是

]*id="test"[^>]*> 结束符使用反向引用 说明一下:

(?'分组名'表达式) 表示将表达式匹配到的内容放入分组中。

k'分组名' 表示引用之前的分组。

上面的例子中 (?'tag'span) 表达式是 span 如果匹配到这四个字符的话,放进名称为 tag 的组中。那么后面k'tag' 其实就是匹配 span字符。

中间部分情况比较多:一类是普通字符,包含类似这样的标签,直接使用 ([dD])

一类是span的标签,我们同样,定义一个计数器 c 专门处理它:

遇到开始标签时 c+1 使用 (?'c']*>) // 其实是将匹配到的标签推送到c组

遇到结束标签时 c-1 使用 (?'-c']*>) // 其实是如果匹配到结束标签,从c组移除一个匹配项

上面这几个情况可以重复任意次,于是用(......)*,将它们串起来得到

((?'c']*>)|(?'-c']*>)|([dD]))*

最后,加上头尾的两个标签,最终的正则表达式是:

]*id="test"[^>]*>((?'c']*>)|(?'-c']*>)|([dD]))*

如果 #test 不是 span 而是其他标签,为了匹配到任意标签,可以把span替换成 w+

]*id="test"[^>]*>((?'c']*>)|(?'-c']*>)|([dD]))*

匹配结果是:1

2

3

4

5

6

7

hi~

虫虫

早上好。

如果不需要带标签,只要里面的内容,那么加上两个断言

(?<=(]*id="test"[^>]*>))((?'c']*>)|(?'-c']*>)|([dD]))*(?=())

匹配结果是 hi~

虫虫

早上好。

说明一下

(?<=表达式) :前面要包含表达式匹配到的项目,但是不会被匹配进去

(?=表达式) :后面要包含表达式匹配到的项目,但是不会被匹配进去

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值