一个密码规则引起的探索

792 阅读2分钟

一、直接上代码

/((?=.*[0-9])(?=.*[a-z])|(?=.*[0-9])(?=.*[A-Z])|(?=.*[a-z])(?=.*[A-Z]))^[0-9A-Za-z]{6,12}$/

当看到这段正则时一脸蒙蔽这个想表达的是什么。并产生以下疑问:

  1.  ^ 前面居然可以有规则,
  2. (?=pattern)这个是什么意思
  3. /(?=pattern)^/这个组合是什么意思
  4. ^前的(...)这一大坨,组合起来又是什么意思

虽然前面看不懂,但是后面的[0-9A-Za-z]{6,12},还是知道是由数字,字母组成的。

根据我们的猜测,我们先来看下这个正则看下结果:

var reg = /((?=.*[0-9])(?=.*[a-z])|(?=.*[0-9])(?=.*[A-Z])|(?=.*[a-z])(?=.*[A-Z]))^[0-9A-Za-z]{6,12}$/
reg.test('123456') // false
reg.test('abcdefg') // false
reg.test('ABCDEFG') // false
reg.test('ab23C') // false
reg.test('abcdEF') // true
reg.test('ABCDEF234') // true
reg.test('abcdEF234') // true

从结果中我们可以看出,这个正则所表达的意思是

  • 由6到12个字母或者数字组成
  • 必须至少包含大写字母、小写小写、数字中的两种

但是它是如何工作的呢,我们还是不知道其中的原理,但是我们猜测他肯定与上文提到2.(?=pattern)有关系。它到底是什么。不废话,直接上图

看图说话,是说匹配的是位置,不理解没关系。我们来测试 

'study'.replace(/(?=s)/, '#') // #study
'study'.replace(/(?=d)/, '#') // stu#dy
'study'.replace(/(?=^)/, '#') // #study

我们从而得知,是找到匹配的pattern后之前的位置,重点强调匹配到的是位置。

明白了这个,我们来理解下/(?=pattern)^/,及找到符合pattern的开始位置,并且该位置要在^之前,能在^之前的是什么?思考下。

/^^study/.test('study') // true

看到这个应该就明白 ^之前的就只能是^,^是个锚点。

我们在来测试

/(?=\d)^/.test('9') // true
/(?=\d)^/.test('9l') // true
/(?=\d)^/.test('l9') // false

我们现在明白 /(?=\d)^/的意思是以数字开头的字符串。

到这里我们应该明白 /(?=.*[0-9])^/ 的意思是以任意字符(可以无)加数字开头。说白了就是必须包含数字

/(?=.*[0-9])^/.test('9') // true
/(?=.*[0-9])^/.test('9l') // true
/(?=.*[0-9])^/.test('l9') // true

我们应该解开了开文的1、2、3这三个疑问。

我们应该也要猜到/(?=.*[a-z])(?=.*[0-9])^/,这个就是以:

  1. 任意字符加数字开头
  2. 以任意字符加小写字母开头,

说白了就是必须包含小写字母以及数字

----------------------------------------------------------------------------------------

到这里我们应该可以全部理解上述的正则

/((?=.*[0-9])(?=.*[a-z])|(?=.*[0-9])(?=.*[A-Z])|(?=.*[a-z])(?=.*[A-Z]))^[0-9A-Za-z]{6,12}$/

必须包含数字与小写字母,或者数字与大写字母,或者小写字母与大写字母并且由数字、大写字母、小写字母组成长度为6到12个

--------------------------------------------------------------------------------------

感谢你的观看。

第一次写博客,写的不好请指出。

______________________________________________________________________________________________

追加个问题
1、给出(?=pattern)是匹配pattern 前的位置而(?<=pattern)是匹配pattern后面的位置,能否使用(?<=pattern)改造下上面的正则 得出一样的规则
2、上文图片中有说(?!pattern)是不匹配pattern的前面,是否也可使用他来改造

给点提示

1、
`study`.replace(/$/, '#') // study#
`study`.replace(/$(?<=y)/, '#') //study#
`study`.replace(/(?<=d)/, '#') // stud#y

2、
`study1`.replace(/(?![a-z])/g, '#') //study#1#
`study`.replace(/(?![a-z])/g, '#') //study#