先要谈谈在JS中,正则表达式的匹配方式是怎么样的
- 有一个例子,如下图,我想将字符串里面的
!dare you!和!an!两个字符串匹配出来,于是我使用了正则表达式/!.+!/去匹配。

匹配出`!dare you!`和`!an!`两个字符串
但是,我们来看结果,这个正则表达式匹配出来的是!dare you! I have !an!,其中I have并不是我想要匹配出来的字符串,这是为什么呢?请看JS正则表达式的匹配方式:

匹配结果不尽如人意
- 正则表达式的匹配方式
1.首先在how !dare you! I have !an! apple这个字符串中,使用/!.+!/进行匹配,那么这个正则式首先寻找的是一个感叹号!,如下图:

匹配到!号
2.匹配到!后,他会继续向后匹配感叹号,但是后面的是字母d,不是感叹号,于是/!.+!/正则就会开始匹配.,而.这个符号可以匹配除换行符外的全部字符,于是它就一直匹配到了最后,直到文本结束:

.号一直匹配到最后
3..号匹配完毕后,开始匹配后面的!,于是正则/!.+!/开始往回匹配感叹号!,一直匹配到an后面的!,发现符合规则了,于是匹配出来的就是这一串字符串!dare you! I have !an!:

最后匹配结果
贪婪模式
上面的匹配模式就是贪婪模式的匹配方式,贪婪模式也是正则表达式的默认匹配方式。
非贪婪模式的匹配方式
- 如果想要对该字符串进行非贪婪模式的匹配,我们就需要对正则
/!.+!/进行改写,改写成如下代码:
var b = /!.+?!/g
其中,g表示采用全局匹配的模式进行匹配,而?则会使该正则式使用非贪婪模式进行匹配,该正则就会以最小的.的重复数进行匹配。
它的匹配结果如下图,刚好符合了要求,匹配出了!dare you!和!an!两个字符串

非贪婪模式匹配结果
- 非贪婪模式的匹配方式
1.与贪婪模式一样先匹配!,然后进行.的匹配,但是与贪婪模式不同的是,它每匹配一次.,就会往后匹配一次!,于是就出现了如下图的结果:

非贪婪模式匹配`!`和`.`
2.然后匹配成功了后面的!后,因为g是全局匹配,所以该正则又会从头开始匹配第一个!,到了!an!后,匹配成功第一个!和两个.,以及后面的!,于是!an!也被匹配上了,然后该正则又剩下的字符串开始从新匹配,而后面因为不能匹配出第一个!,于是就没有匹配出来:

匹配出`!an!`
3.所以我们最后得到的就是符合要求的!dare you!和!an!两个字符串
总结:
1.JS中的正则表达式的贪婪模式和非贪婪模式主要是匹配方式上有所不同;
2.正则中的?可以使正则式采用非贪婪模式进行匹配;
3.正则中的g可以进入全局匹配的模式;
4.正则中的+是一个或多个的意思,如果没有,则不能进行匹配;
