續接上文的密碼校驗要求:javascript
這個需求有兩個難點,一,是如何使用正則匹配全部半角英文標點符號,二,是如何驗證密碼段中在要求的四種(大寫字母,小寫字母,數字,標點符號)類型中至少存在三種。java
第一個難點:如何使用正則匹配全部半角英文標點符號在上文中已經得以解決,因此在這裏咱們主攻第二個難點並完成完整的符合需求的表達式。正則表達式
知足需求:徹底符合上述圖片的校驗需求,密碼段中在要求的四種(大寫字母,小寫字母,數字,標點符號)類型中至少存在三種學習
解決方案:靈活運用正則中的零寬度負先行斷言:code
^(?!^[0-9a-z]+$)(?!^[0-9A-Z]+$)(?!^[0-9\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]+$)(?!^[a-zA-Z]+$)(?!^[a-z\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]+$)(?!^[A-Z\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]+$)(?!^[A-Z\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]+$)[a-z0-9A-Z\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]+$
能被匹配到的則知足上述圖片需求圖片
零寬斷言是正則表達式中的一種進階使用方法,靈活運用零寬斷言能讓正則表達式變得更爲簡練,而且使其功能變得更爲強大。ip
正則的零寬斷言通常有如下四種:字符串
借用司徒正美大大的解釋入門
但惋惜的是javascript並不支持(?<=exp)和(?<!exp)的用法。而咱們此次使用的則是零寬度負先行斷言原理
零寬度負先行斷言原理解釋:
(?!exp)這個斷言的用法是:只有當字符串右側不出現匹配exp的字符串時才匹配正則表達式。
咱們先從一個簡單的例子講解:
若是咱們要匹配一串字符,全部字符必須爲小寫字母或者數字,而且必需要有小寫字母。
那麼換一種思路,就是咱們的字符串必須爲小寫字母或數字構成,而且不能爲純數字。
因此咱們使用零寬度負先行斷言,則能夠寫成
^(?!^[0-9]+$)[a-z0-9]+$
斷言(?!^[0-9]+$)則表示純數字的組合不能被匹配。
把例子加深一下:
咱們要匹配一串字符,全部字符必須爲小寫字母或者數字,而且必須同時有小寫字母和數字的存在。
那麼換一種思路,就是咱們的字符串必須爲小寫字母或數字構成,而且不能爲純數字或者是純小寫字母。
因此咱們使用零寬度負先行斷言,則能夠寫成
^(?!^[0-9]+$)(?!^[a-z]+$)[a-z0-9]+$
斷言(?!^[0-9]+$)則表示純數字的組合不能被匹配;斷言(?!^[a-z]+$)則表示純小寫字母的組合不能被匹配。
兩者相組合,就可以把全部純數字和純小寫字母的組合給排除掉了,剩下的就是同時有小寫字母和數字的組合。
怎麼樣,思路出來了嗎?
把例子再次深化:
咱們要匹配一串字符,全部字符必須爲小寫字母或者數字或者大寫字母,而且必須至少有三種字符中的兩種。
那麼咱們整理下思路,實際上就是咱們的字符串必須爲上述三種字符構成,而且不能爲純數字或純小寫字母或純大寫字母。
因此咱們使用零寬度負先行斷言,則能夠寫成
^(?!^[0-9]+$)(?!^[a-z]+$)(?!^[A-Z]+$)[a-z0-9A-Z]+$
這樣作,就能夠把純數字(?!^[0-9]+$),純小寫字母(?!^[a-z]+$),純大寫字母(?!^[A-Z]+$)通通排除了。
練級完成,是時候面對大BOSS了
在上一篇JS的JS正則密碼複雜度校驗文章中,咱們知道了要匹配全部的半角表單符號的正則表達式是:
/[\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]/
配合上面的斷言語句,咱們能夠去單挑boss了:
驗證密碼段中在要求的四種(大寫字母,小寫字母,數字,標點符號)類型中至少存在三種,咱們就能夠將思路轉換爲:
在只有上述四種類型範圍的字符串中,找出全部從頭至尾只有兩種如下字符的字符串並將它們排除就能夠了。
那麼根據排列組合,咱們須要排出的就是
數字和小寫字母(?!^[0-9a-z]$),
數字和大寫字母(?!^[0-9A-Z]$),
數字和符號(?!^[0-9\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]$),
小寫字母和大寫字母(?!^[a-zA-Z]$),
小寫字母和符號(?!^[a-z\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]$)
還有大寫字母和符號(?!^[A-Z\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]$)
因而乎,最後的正則成品:
^(?!^[0-9a-z]+$)(?!^[0-9A-Z]+$)(?!^[0-9\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]+$)(?!^[a-zA-Z]+$)(?!^[a-z\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]+$)(?!^[A-Z\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]+$)(?!^[A-Z\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]+$)[a-z0-9A-Z\x21-\x2f\x3a-\x40\x5b-\x60\x7B-\x7F]+$
就能知足咱們的需求
正則表達式的學習入門比較容易,上手也不難。在面對一些很長的正則表達式或者看似奇葩的正則表達式匹配需求時,咱們不妨靜下心來,慢慢地去分析它們,找到箇中規律以後,正則表達式的迷霧也就被揭開了。而正則表達式這把神器,也能被咱們爲所欲爲地揮舞了。