读懂那些火星(正则)表达式:捕获元与非捕获元
想读懂世间所有的那些变态正则表达式?做梦,年纪轻轻,想啥呢,尽自己最大努力学就行 引子JS学了用了也快一两年了,对象啥的找到了也会用了,继承啥的也入门了,但看别人的框架代码,总是会随时卡壳,有一个重大的原因,就是那看不懂的一串串火星文字(正则表达式),学习吗,就是查缺补漏,不怕你不懂,就怕你觉得自己全懂了。说正事之前,先推荐一款软件:RegexBuddy,无论是做正则的测试还是过程的研究,都是一款利器。 知识汇总语法复习,重点三块知识:
正则表达式解析原理:这个不算我等渣暂时能写出来的,推荐一篇 层层递进剖析贪婪匹配先理解贪婪匹配,正则表达式的日常应用基本也就满足了,在菜鸟教程的语法开篇就已经提的很详细了,比如有一个regex:/Chapter[1-9]/,这个字符串我们只能匹配到Chapter1-Chapter9,也就是Chapter的一级标题,但我们想匹配到二级或者三级标题怎么办,这里就用到了贪婪匹配,就是在目标字符串中最大化的匹配结果,将前面的regex:/Chapter[1-9]/改成/Chapter[1-9]+/,这样我们就能匹配Chapter1,Chapter12,Chapter123,但如果我们将其改为/Chapter[1-9]?/,这个无论/Chapter后面输入多少个数字,都只能最多匹配一个数字,这里就是Chapter1,但与最初的表达式不同的是,这个表达式也能匹配裸的Chapter,这就是所谓(X?),问号前面的X可出现0次或者1次,当我们将其改为/Chapter[1-9]星号(避开markdown语法)/,这个最后可以达到?和+共同的结果,也就是所谓的,x出现任意次数。上面这些我们也可以通过[n,m]即n=<x<=m来匹配x出现的次数,{0,1}实现的效果等价与?,而{1,}等价于+,{0,}等价于星号(避开markdown语法)。 懒惰匹配与贪婪匹配成对的另一个叫懒惰匹配,在前面出现的所有贪婪匹配后面加上一个?,这样整个表达式就成了懒惰匹配,可以理解为最小化匹配,比如/Chapter[1-9]+/匹配Chapter12345的结果是Chapter12345,但/Chapter[1-9]+?/匹配的结果就是Chapter1;/Chapter[1-9]{2,4}/匹配结过是Chapter1234,而/Chapter[1-9]{2,4}?/结过是Chapter1234,这就是所谓的最小化去匹配结果,取下限,通常称为懒惰模式。 捕获元与非捕获元以前看到什么?:,?=,?!,用的少,也就没留意,最近大面积灾荒,经常看到,甚是恐惧,以至于前面在读gulp里面碰见个regex表达式:/-[0-9a-f]{8,10}-?/(匹配app-7ef5d9ee29.css这一类表达式中的md5值),就一头栽进去,'-?'到底又有什么特殊的含义,最后才发现,那TMD就是一个贪婪匹配,你个蠢货,但确实搞不懂源码作者在想啥,也许是我没碰到app-7ef5d9ee29-any.css这样的文件名,要不非得多加个'-?'干啥,让我直往坑里跳。 var str ='mom and dad and baby'; var pattern = /mom( and dad( and baby))/; //捕获元形式 var pat= /mom(?: and dad(?: and baby))/; //非捕获元形式 var mat = pattern.exec(str); var match = pat.exec(str); console.log(mat); console.log(match);
var str ='ababa'; var pattern = /ab(?:a)/g; var pat= /ab(?=a)/g; var mat = pattern.exec(str); var match = pat.exec(str); console.log(mat); console.log(match); mat = pattern.exec(str); //全局模式,第二次匹配 match = pat.exec(str); //全局模式,第二次匹配 console.log(mat); console.log(match);
从上面代码运行的截图可以看出区别一,也就是(?:pattern)的形式的捕获元匹配的结果会保存在最终的结果中,而(?=pattern);区别二看的不是很明显,这时我们需要依靠RegexBuddy,这个过程中到底发生了什么?看运行截图,如果你够仔细,你可以发现区别,第一次匹配到结果,开始第二次匹配时,?:是从字符索引3开始,而?=是从2开始,这就是前面所说的消耗字符与不消耗字符。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |