【regex】用环视实现固化分组

用环视实现固化分组

首先看这篇博文的“老几”应该知道固化分组的概念。但是也有可能是读者冲着环视进来的。所以还是有必要的说一下固化分组的概念。

咱知道,NFA 的灵魂是回溯,固化分组也是 NFA 特有的,而固化分组的任务却是让你丢弃前面的备用状态。那固化分组的作用是什么呢?

想想你有没有这样的需求,如果你写了这样一个正则

[0-3]?\d

去匹配“3”这个字符串

毫无疑问,3应该是被\d匹配到了,因为[0-3]?是匹配优先的,于是,先是被[0-3]?匹配到,然后发现\d不能被匹配,于是回溯,控制权转移到\d,然后由\d匹配到3,但是我们的需求是让[0-3]?去匹配到,而不是让\d去匹配到,这时候就可以用固化分组,把原先的正则改为

(?>[0-3]?)\d

这时候[0-3]?就能匹配到3了,如果你的正则引擎不支持固化分组,没关系,这篇博文的目的就是可以用环视来实现一个固化分组。

想想,其实固化分组和占有量词非常非常的相似,占有量词是指++, ?+, *+之类的东西,这些量词一旦匹配到了就不会交出已经匹配的字符了,换一种说法,它会丢弃之前已经保存的备用状态。固化分组也是一样的,它也会将匹配到的留给自己,不会交出任何一个字符。

好了,回到正题,我们如何用环视实现一个固化分组,还记得环视相关的知识吗?环视不明确匹配字符,而是匹配一个位置!那这样就好办了啊,比如我们想要固化的是3这个子串,并且想要它为可选的

我们先用环视匹配这个子串左边的位置

(?=3?)

看起来好像没有一点问题,其实这时候3已经被固化了,因为没有保存任何的备用状态,但是这样的话有个问题。

我们仅仅是匹配位置,所以下次开始匹配的位置还是在原地,我们得匹配点子串,让位置前移才行,于是改进之后

(?=(3?))\1

捕获组捕获到3?之后反向引用。

接下来看个新例子,现在我们把正则表达式这样写:

(?=([0-4]?))\1\d

然后去匹配3,哈,你发现匹配失败了,这就是我们想要的结果,3[0-4]?匹配了!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值