1. 程式人生 > >正則表示式-零寬斷言

正則表示式-零寬斷言

題目很簡單,對字串進行校驗,規則如下:

1.長度至少有6位

2.包含小寫字母

3.包含大寫字母

4.包含數字

5.僅由數字和字母組成

對於2.3.4這3個條件,沒辦法寫在一個正則裡面,於是搜尋發現了零寬斷言這種正則形式,這種形式是以括號包起來的子表示式存在的,由以下兩種形式:

  • 正向零寬斷言     表示式為:(?=exp)       意為當該位置的字元需滿足正則exp才能,整個正則表示式才能成功匹配
  • 負向零寬斷言     表示式為:(?!exp)        意為當該位置的字元不能滿足正則exp時,整個正則表示式才能成功匹配

所謂零寬斷言,其實語義上分兩部分:零寬就是指這個括號內的正則表示式長度位零,不用作正則提取;斷言就是指這是一個判斷語句類似與if。

回到剛才的題目,答案可以這麼寫:

regex = '^(?=.*?[0-9])(?=.*?[a-z])(?=.*?[A-Z])[0-9a-zA-Z]{6,}$'

^後的3個括號的意思分別是包含數字,包含小寫字母,包含大寫字母

雖然答案通過了,但是還是覺得不對勁,按照以前的正則知識,正則是有順序的,^後的3個括號體現出來的順序應該是 數字-小寫字母-大寫字母,但是事實上正則並沒有按照這種順序解釋,於是又回到零寬這個屬性上來,既然是"零寬"的,那麼單獨看這3個括號中的任意一個括號時,其它兩個括號都是零寬即可以忽略的,也就是說他們之間是互不影響的,這一點純屬個人理解,如果有不對,歡迎指正。

這個題不適合用負向零寬斷言,不過稍微變通一下還是能寫出來的:

regex = '^(?![0-9a-z]+$)(?![a-zA-Z]+$)(?![0-9A-Z]+$)[0-9a-zA-Z]{6,}$'