上圖是官方文檔的介紹,總結一下講了兩個知識點 ①是否獲取匹配並保存匹配的值、②正向預查和反向預查。 1:解釋是否獲取匹配並保存匹配的值 ()表示捕獲分組,獲取匹配,()把每個分組裡的匹配的值保存起來 (?:)表示非捕獲分組,獲取匹配,非捕獲分組匹配的值不會保存起來,可以提高程式執行速度 (?=?!? ...
上圖是官方文檔的介紹,總結一下講了兩個知識點 ①是否獲取匹配並保存匹配的值、②正向預查和反向預查。
1:解釋是否獲取匹配並保存匹配的值
- ()表示捕獲分組,獲取匹配,()把每個分組裡的匹配的值保存起來
- (?:)表示非捕獲分組,獲取匹配,非捕獲分組匹配的值不會保存起來,可以提高程式執行速度
- (?=?!?<=?<!)表示非捕獲分組,不獲取匹配,也不保存匹配的值
舉例說明:
// 是否獲取匹配 測試文本 abxoxcd
..(xox).. 匹配 abxoxcd
..(?:xox).. 匹配 abxoxcd ..(?=xox).. 匹配 abxo
獲取匹配,一般匹配到了字元之後,該字元就被消耗、輸出。不獲取匹配,不會消耗字元。
// 是否保存匹配的值 測試文本 AAABBCaaA E666FF (A)\\1* 匹配 AAA、A (\\w)\\1+ 匹配 AAA、BB、aa、666、FF (?:A)(B)\\1* 匹配 ABB
因為非捕獲分組不保存匹配的值,所以 (?:A)(B)\\1* 匹配 ABB 第一個\\1表示(B)這個捕獲組捕獲到的值。 “註意:反向引用表示捕獲到的值,而不是再次使用正則表達式”
這裡用到了一個新的知識點,反向引用。
1、正則表達式中 “\number” 表示反向引用,表示引用一個捕獲組,需要和小括弧 “()” 一起使用
2、正則捕獲組的下標從 0 開始,下標為 0 的組是整個表達式,下標為 1 的表示從左到右開始的第一個左括弧所包含的值,後面的數字以此類推
3、捕獲組在匹配成功時,會將子表達式匹配到的內容,保存到記憶體中一個以數字編號的組裡,可以簡單的認為是對一個局部變數進行了賦值,這時就可以通過反向引用的方式,引用這個局部變數的值。
4、反向引用必須要與捕獲組一同使用,如果沒有捕獲組,而使用了反向引用的語法,不同語言的處理方式不一致,有的語言會拋異常,有的語言會當作普通的轉義處理
2:解釋正向預查和反向預查
// 前瞻: exp1(?=exp2) 查找exp2前面的exp1 // 後顧: (?<=exp2)exp1 查找exp2後面的exp1 // 負前瞻: exp1(?!exp2) 查找後面不是exp2的exp1 // 負後顧: (?<!exp2)exp1 查找前面不是exp2的exp1
舉例說明:
// 正向預查和反向預查 測試文本 abxoxcd ..(?=xox) 匹配 ab ..(?=oxo) 匹配不到
(?=xox).. 匹配xo (?<=xox).. 匹配 cd
預查只需要記住:1、環顧全局定位到非捕獲組;2、不獲取匹配(不消耗字元),不保存匹配的值(不能使用反向引用)
加餐
提問:強密碼(必須包含數字、小寫字母和大寫字母三種字元,即這三種字元的組合,且不能使用特殊字元,長度在8-16之間),你認為必須是 1個數字+1個小寫字母+1個大寫字母 這種順序嗎?
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{8,16}$
(?=.*[0-9])表示任意字元+一個數字
(?=.*[a-z])表示任意字元+一個小寫字母
(?=.*[A-Z])表示任意字元+一個大寫字母
[0-9a-zA-Z]{8,16}表示8-16個數字、大小寫字母
當有多個正向預查規則時它們是併列的,不是串列的
舉例說明:
測試文本 abc2abc \\d(?=a)(?=b) 匹配不到 \\d(?=a)(?=.b) 匹配 2 當然這是為了演示它的規則,其實可以寫 \\d(?=ab)
這裡主要的原因是:不獲取匹配(不消耗字元)。
對於 ^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{8,16}$
其實整個正則表示可以分為三部分:
/^(?=.*[0-9])[0-9a-zA-Z]{8,16}$/
/^(?=.*[a-z])[0-9a-zA-Z]{8,16}$/
/^(?=.*[A-Z])[0-9a-zA-Z]{8,16}$/
待匹配字元串必須同時滿足這三部分才可以
【參考】
- https://www.jianshu.com/p/9c4979a3b7e4
- http://www.45fan.com/article.php?aid=19101105382209663550874595
- https://www.runoob.com/java/java-regular-expressions.html
- https://www.runoob.com/regexp/regexp-syntax.html
- https://www.cnblogs.com/archermeng/p/7537244.html