正则基础之——非捕获组

非捕获组: (?:Expression)

接触正则表达式不久的人,通常都会对非捕获比较迷惑,为什么要有非捕获组?作用是什么?应该在什么场景下使用?

说到非捕获组,首先要了解什么是捕获组,详细内容参考 正则基础之 —— 捕获组( capture group  

1 、为什么要有非捕获组

一旦使用了“ () ”,就会默认为是普通捕获组,从而将“ () ”内表达式匹配的内容捕获到组里。但是有些情况下,不得不用“ () ”,但并不关心“ () ”中匹配的内容是什么,后面也不会引用捕获到的内容,这带来了一个副作用,记录这些捕获组就会占用内存,降低匹配效率。

设计非捕获组的目的就是为了抵消这种副作用。   只进行分组,并不将子表达式匹配到的内容捕获到组里。

2 、不得不使用 () ,由此可能带来副作用的情况

以下举例中只说明场景,举例比较简单,实际应用涉及到时可能会比较复杂。

a)          使用“ | ”表示“或”的关系时,用“ () ”限制范围

举例:匹配 0 100 的数字

正则表达式: ^([1-9]?[0-9]|100)$

如果不用“ () ”来限制“ | ”的范围,结果就会出错,详见“ | ”的解释。

b)          使用量词限定一个子表达式整体的匹配次数

举例:匹配 HH:mm:ss 格式时间

正则表达式: ([01][0-9]|2[0-3])(:[0-5][0-9]){2}

这里的“ {2} ”是对前面的“ :[0-5][0-9] ”整体作修饰,因此要用“ () ”来限定修饰的范围。

当然,量词还可以是 ? * + {m} {m,n} {m,} ,以及非贪婪模式的量词等。

c)          某些时候为了使捕获组的编号可控,可能会用到非捕获组,这种应用不多,这里不赘述。

3 、什么时候该用非捕获组

非捕获组主要是在涉及到效率时才考虑使用,而效率通常都是相对的,需要综合考虑。

不考虑效率的场合,可以不用非捕获组,以提高正则表达式的可读性。

一些非常简单的正则中,如果使用了非捕获组,因为要解析这种语法,反而可能会降低匹配效率。

一般在较复杂,“ () ”使用较多的正则表达式中可以考虑使用非捕获组,比如验证日期的正则表达式。

未使用非捕获组的正则:

^((?!0000)[0-9]{4} -((0[1-9]|1[0-2]) -(0[1-9]|1[0-9]|2[0-8]) |(0[13-9]|1[0-2]) -(29|30) |(0[13578]|1[02]) -31 )|([0-9]{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00) -02 -29 )$

由于这里的“ () ”都是用作分组,并不关心分组匹配到的内容,而且使用的 () 很多,影响匹配效率,所以这个正则表达式中可以使用非捕获组。

^(?:(?!0000)[0-9]{4} -(?:(?:0[1-9]|1[0-2]) -(?:0[1-9]|1[0-9]|2[0-8]) |(?:0[13-9]|1[0-2]) -(?:29|30) |(?:0[13578]|1[02]) -31 )|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00) -02 -29 )$

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值