您的位置:首页 > Web前端 > JavaScript

正则表达式——分组/不捕获/断言/其他

2016-10-13 16:34 225 查看
看了看上一篇还是六月份的博客,哎,满满的罪恶,忙是一部分,还有原因就是写着写着有些其他想法,打乱了顺序。

不说了,现在继续,这篇总结下正则表达式,前面有一篇正则表达式备忘篇,收集了一些常用的正则表达式,紧急的话可以直接拿来用,但正则作为不管前台后台哪哪都需要用到的功能,怎么写还是必须要会 滴,简单的应该都会,就不总结了,这一篇总结下很实用但高于入门一丢丢的知识。

分组:就是用一个小括号()把一个子表达式包围起来,这就是一个分组。这样做的好处是:

1,将相同规律的字符串写同一个子表达式,将这个表达式变成一个分组,就可以通过指定循环次数就可以完成匹配,而不需要写多个子表达式。

2,如果有的子表达式,后面还需使用,转化为分组后,就可以通过后向引用从而简化整个表达式,这个注意,不要随便用,后面说。

现在通过实例来详细讲解下这两个作用。先讲第一个作用。

举个例子:IP地址,没有分组的时候,我们这样写

\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}

用了分组后,就可以这样写

\d{1,3}(.\d{1,3}){3}    

是不是简单多了,大大的缩减了正则表达式,第二个作用,还是以ip地址为例,\d{1,3}这个表达式使用了两次,我们将它设为一个分组,通过后向引用简化正则表达式,引用方法\k或$k,这样

(\d{1,3})(.\1){3}

事实上,这样是错的!





分组的时候,整个正则表达式是第0组,然后从左到右依次排,我们上面(\d{1,3})就是第1组,所以我后面用了\1引用,但是要注意的问题是,\1引用的只是匹配后的文本,而不是表达式,比如ip地址127.0.0.1,第一组匹配的是127,所有后面都只能匹配127.127.127



这样不能用,但是像这种的<div></div>就可以引用了



不捕获:不捕获就是在分组的前面加上?:,可以在不需要捕获分组的表达式中使用,加快表达式执行速度

像我们上面<(div)>.*<\/\1>这个正则表达式中,我们用\1捕获了第一个分组(div),但是如果我们将这个正则表达式转变成这样<(?:div)>.*<\/\1>,那么\1就不能捕获到第一个分组了,只能捕获第一个出现非?:的分组为\1



注意:?:仍然是完整匹配,只是不捕获分组,注意和接下来要讲的断言的区别



断言:指明某个字符串的前面和后面,将会出现满足某种规律的字符串,它只是一个条件,帮助我们找到真正的字符串,它自己本身是不会匹配的。

还是以我们上面的div为例,如果我们有一个需求要获取div之间的内容且返回的字符串不包括<div></div>,是不是不好写,现在我们有了断言就会很好写了。

(?=X):零宽度正先行断言,比如:/.*(?=/d)/就表示后面有任意数字的任意字符串才是我们想要的字符串,但是后面的数字不是我们想要的,所以后面的数字不会匹配。

(?<=X):零宽度正后发断言,比如:/(?<=/d).*/就表示前面有任意数字的任意字符串才是我们想要的字符串,但是前面的数字不是我们想要的,所以前面的数字不会匹配。

(?!X):零宽度负先行断言,同(?=X)一样,只是它代表否,即后面不能带有X。

(?<!X):零宽度负后发断言,同(?<=X)一样,只是它代表否,即前面不能带有X。

现在我们可以用(?=X)和(?<=X)来获取两个div之间的内容,即/<?<=div>*<?=\/div>/

注意:

1,断言也不会捕获分组,所以\k无法获取到分组

2,发现javascript不支持<?<=>,没办法,曲线救下国,用replace替换下div吧。



3,断言不是完整匹配,这里演示下<?=>



好了,主要的介绍完了,接下介绍一些其他的小知识点

.*和.*?的区别:这涉及到贪婪模式和懒惰模式。

贪婪模式:在满足条件的情况下,尽可能多的匹配字符。比如:<div>.*</div>



懒惰模式:在满足条件的情况下,尽可能少的匹配字符。比如:<div>.*?</div>



PS:.*表示的是除去换行符之后的所有任意字符,如果要包括换行符就用\s\S

暂时这些,后面如果还有想补充的再补充。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息