javascript 正则表达式-零宽断言

http://buzheng.org/blog/regex-zero-width-assertion/

正则表达式里面比较高级的应用就属于零宽断言了。那么什么是零宽断言呢?拆分法从字面上分析一下,零宽,即宽带为0,意味者不会返回匹配的字符,以为匹配的是当前字符的位置。断言,就是预言、假设,意味着从此处假设存在什么情况。那么零宽断言的意思就是假定从此位置开始满足某种情况。

根据断言字符串位于当前位置的前后关系,分为正向和反向断言,根据断言肯定和否定的语气,又有正向否定断言和反向否定断言。肯定即断言存在该字符串、否定即相反的意思:存在的不是该字符串,总之概念比较绕口,下表介绍的时候顺便给出英文:

(?=X)正向断言,假定该位置后跟的是X

zero-width positive lookahead

(?!X)正向否定断言,假设该位置后跟的不是X

zero-width negative lookahead

(?<=X)反向断言,假设该位置前跟的是X

zero-width positive lookbehind

(?<!X)反向否定断言,假设该位置前跟的不是X

zero-width negative lookbehind

举例:

(?=X) 正向断言

[^s]+?(?=ing) 来匹配 having doing listing,会匹配出 hav, do, list,注意:并不会匹配出ing,因为ing是零宽断言的部分。

(?!X) 正向否定断言

一个用户注册功能的密码有如下要求:由数字和字母组成,并且要同时含有数字和字母,且长度要在8-16位之间。

如何分析需求?拆分!这就是软件设计的一般思路了。于是乎,拆分需求如下:

1,不能全部是数字

2,不能全部是字母

3,必须是数字或字母

只要能同时满足上面3个要求就可以了,写出来如下:

^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$

分开来注释一下:

^ 匹配一行的开头位置

(?![0-9]+$) 预测该位置后面不全是数字

(?![a-zA-Z]+$) 预测该位置后面不全是字母

[0-9A-Za-z] {8,16} 由8-16位数字或这字母组成

$ 匹配行结尾位置

(?<=X) 反向断言

(?<=hell)[a-z]+ 来匹配test hellen hellas helloween,会匹配出 en, as, oween

(?<!X) 反向否定断言

[a-z]+(?<!hell)en 来匹配testen hellen hellas helloween,会匹配出testen和helloween

注:所有的案例都在UE下进行测试。