正则匹配原理之 逆序环视深入 .
前端  /  管理员 发布于 7年前   207
说明:部分内容有待进一步研究和修正,因为最近工作太忙,暂时抽不出时间来,未研究过的可以跳过这一篇,想研究的不要被我的思路所左右了,有研究清楚的还请指正1 问题引出
前几天在CSDN论坛遇到这样一个问题:
var str="8912341253789";
需要将这个字符串中的重复的数字给去掉,也就是结果89123457。
首先需要说明的是,这种需求并不适合用正则来实现,至少,正则不是最好的实现方式。
这个问题本身不是本文讨论的重点,本文所要讨论的,主要是由这一问题的解决方案而引出的另一个正则匹配原理问题。
先看一下针对这一问题本身给出的解决方案。
图3-1 逆序环视匹配原理图
正则表达式“(?<=SubExp1)SubExp2”的匹配过程,可分为主匹配流程和子匹配流程两个流程,主匹配流程如下图所示。
图3-2 主匹配流程图
主匹配流程:
1、 由位置0处向右尝试匹配,在找到满足“(?<=SubExp1)”最小长度要求的位置前,匹配一定是失败的,直到找到这样一个的位置x,x满足“(?<=SubExp1)”最小长度要求;
2、 从位置x处向左查找满足“SubExp1”最小长度要求的位置y;
3、 由“SubExp1”从位置y开始向右尝试匹配,此时进入一个独立的子匹配过程;
4、 如果“SubExp1”在位置y处子匹配还需要下一轮子匹配,则再向左查找一个y',也就是y-1重新进入独立的子匹配过程,如此循环,直到不再需要下一轮子匹配,子匹配成功则进入步骤5,最终匹配失败则报告整个表达式匹配失败;
5、 “(?<=SubExp1)”成功匹配后,控制权交给后面的子表达式“SubExp2”,继续尝试匹配,直到整个表达式匹配成功或失败,报告在位置x处整个表达式匹配成功或失败;
6、 如有必要,继续查找下一位置x',并开始新一轮尝试匹配。
子匹配流程如下图所示。
图3-3 子匹配流程图
子匹配过程:
1、 进入子匹配后,源字符串即已确定,也就是位置y和位置x之间的子字符串,而此时的正则表达式则变成了“^SubExp1$”,因为在这一轮子匹配当中,一旦匹配成功,则匹配开始位置一定是y,匹配结束位置一定是x;
2、 子表达式长度固定时,要么匹配成功,要么匹配失败,返回匹配结果,并且不需要下一轮子匹配;
3、 子表达式长度不固定时,区分是非贪婪模式还是贪婪模式;
4、 如果是非贪婪模式,匹配失败,报告失败,并且要求进行下一轮子匹配;匹配成功,丢弃所有回溯状态,报告成功,并且不再需要尝试下一轮子匹配;
5、 如果是贪婪模式,匹配失败,报告失败,并且要求进行下一轮子匹配;匹配成功,丢弃所有回溯状态,报告成功,记录本次匹配成功内容,并且要求尝试下一轮子匹配,直到取得最长匹配为止;
在特定的一轮匹配中,x的位置是固定的,而逆序环视中的子表达式“SubExp1”,在报告最终的匹配结果前,匹配开始的位置是不可预知的,需要经过一轮以上的子匹配才能确定,但匹配结束的位置一定是位置x。
当然,这只是针对特定的一轮匹配而言的,当这轮匹配失败,正则引擎传动装置会向前传动,使x=x+1,再进入下一轮匹配尝试,直到整个表达式报告匹配成功或失败为止。
至此逆序环视的匹配原理已基本上分析完了,当然,还有更复杂的,如“SubExp1”中既包含贪婪模式子表达式,又包含非贪婪模式子表达式,但无论怎样复杂,都是要遵循以上匹配原理的,所以只要理解了以上匹配原理,逆序环视也就没什么秘密可言了。
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号