詳解正規表示式

2020-07-16 10:05:40

正規表示式語言由兩種基本字元型別組成:原義(正常)文字字元和元字元。

相關推薦:
1. 正規表示式語法教學(含線上測試工具)
2. PHP正規表示式極速入門視訊教學

元字元使用正規表示式具有處理能力。元字元既可以是放在[ ] 中的任意單個字元(如 [a]表示匹配單個小寫字元 a),也可以是字元序列(如 [a-d] 表示匹配 a 、b、 c、 d 之間的任意一個字元,而 w 表示任意英文字母和數位及下劃線),常見的元字元如下:

常見的元字元

字元描述特別說明
.匹配除換行符(n)以外的任意字元~
[abcde]匹配 a b c d e 之中的任意一個字元所有字元是 的關係
[a-h]匹配 ah之間的任意一個字元~
[^fgh]不與 fgh之中的任意一個字元匹配在 中括號[ ] 的第一個字元前加上 ^ 表示 取反
不匹配中括號裡面出現的任意字元
w匹配大小寫英文字元及數位 0 到 9 之間的任意一個及下劃線,相當於[a-zA-Z0-9_]~
Ww 相反,相當於 [^a-zA-Z0-9_]~
s匹配任意的空白符,相當於 [fnrtv]~
Ss相反,相當於 [^s]~
d匹配任何 0 到 9 之間的單個數位,相當於 [0-9]~
Dd 相反,相當於[^0-9]~
[u4e00-u9fa5]匹配任意單個漢字(中文)(這裡用的是 Unicode 編碼表示的漢字)~
b匹配單詞的開始或結束~
^匹配字串的開始放在中括號的第一個字元前 則變為 取反的意思
$匹配字串的結束~

正規表示式限定符

作用:限定這個符號前面 一個 單元 多出現的次數
單元:

  1. 如果前面出現的是一個字元的話,則這一個字元就為一個 單元
  2. 如果前面我們用小括號把一個很長的字串括起來的話,那麼整個小括號裡面都算是一個 單元

上面的元字元都是針對單個字元匹配的,要想同時匹配多個字元的話,還需要借助限定符,下面是一些常見的限定符(下表中 n 和 m 都是表示 整數。)

字元描述特別說明
*匹配 0 到 多 個元字元,相當於 {0,}~
?匹配 0 到 1 個元字元, 相當於 {0,1}~
+匹配至少 1 個元字元,相當於 {1,}~
{n}匹配 n 個元字元~
{n,}匹配至少 n 個元字元~
{n,m}匹配 n 到 m 個元字元~
b匹配單詞邊界~
^字串必須以指定的字元開始~
$字串必須以指定的字元結束~

說明 - 特例

  1. 可以將多個元字元或者原義文字字元用括號括起來形成一個 分組,比如 ^(13)[4-9]d{8}$ 表示任意以 13 開頭的移動手機號碼。
    1. abcabcabc+ 表示 最後的字母 c 出現 1 次或 多次;
    2. (abcabcabc)+ 表示 整個字串 abcabcabc 出現 1 次或 多次。
  2. 可以使用 | 來表示 的關係,例如 z|j|q 表示匹配 z 、j、q 之中的任意一個字母。其實等價於 [zjq]
    1. ab|cd|ef 表示的是:要麼是 ab、要麼是 cd要麼是 ef
    2. a(b|cd|e)f 表示的是:以a開頭,要麼是 b、要麼是 cd要麼是 e,最後以f結尾。
    3. 總結:|) 的唯一邊界是 小括號( )
  3. [0-9A-Z.?] 這個正則你如何理解?
    1. .? 出現在中括號中時,.? 將變為 普通字元,它就是 點 和 問號。你可以理解為 [ ] 的優先順序要大於. 和 ? 的優先順序。
    2. 此正規表示式將會完全匹配字串 ?aaa.bbb ,記住這裡 . 和 ? 被完全當做了普通字元。

高階1 - 多選結構

多選結構其實就是元字元 | (或)的使用。
界定範圍:開頭、結尾、小括號

正則含義
Windows98|Windows2000|WindowsXP匹配Windows98或者Windows2000或者WindowsXP
^Windows98|Windows2000|WindowsXP$Windows98開頭或者包含Windows2000或者以WindowsXP結尾
注意^$都包含在|的範圍內,因為|的界限只有:開頭、結尾、小括號
Windows(98|2000|XP)Windows然後98 或者2000或者XP

總結:多選結構可以包括很多字元,但不能超越 括號 的界限。

高階2 - 分組與後向參照

分組

  • 我們已經了解怎麼重複單個字元;
  • 但如果想要重複一個字串該怎麼辦?你 可以用小括號來指定子表示式(也叫做分組)
  • (d{1,3}.){3}d{1,3} 簡單的 IP 地址匹配表示式
  • 但是它也將匹配 256.300.888.999 這種不可能存在的 IP 地址。你能寫一個更準確的正則?
  • ((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)

反向參照

  • 使用小括號指定一個子表示式(分組)後,匹配這個子表示式的文字可以被捕獲,從而在表示式或其他程式中作進一步的處理。
  • 預設情況下,每個分組會自動擁有一個組號,規則是:以分組的左括號為標誌,從左向右,第一個分組的組號為 1 ,第二個為 2 ,依次類推

範例:

  • b(w+)bs+1b 可以用來匹配重複的單詞
  • 匹配諸如:where where go, tom tom happy

直白解釋:
正規表示式中,前面用小括號進行劃分(分組),後面把小括號匹配到的內容參照到後面來,分別用12等 來表示。(第一個小括號極1...)。如果存在 小括號巢狀小括號的情況 (w+(.?)) 記住:這個時候要以 ( 為標誌 從左往右 數小括號就可以了。

高階3 - 環視(零寬斷言)

  • 環視不匹配任何字元,只匹配文字中的 特定位置。類似於b^$ 那樣。環視不會佔用字元。
  • 環視分為順序逆序兩種:
    • 順序
      • (?=exp) 位置的後面能匹配 exp。例如:(?=d) 當前位置右邊是數位。
      • (?!exp) 位置的後面不能匹配 exp。例如:(?!d) 當前位置右邊不是數位。
    • 逆序
      • (?<=exp) 位置的前面能匹配 exp。例如:(?<=d) 當前位置左邊是數位
      • (?<!exp) 位置的前面不能匹配 exp。例如:(?!d) 當前位置左邊不是數位。

高階4 - 貪婪與懶惰

  • 當正規表示式中包含能接受重複的 量詞 (指定數量的程式碼,例如:+*{3,12} 等)時, 通常的行為是匹配儘可能多的字元
  • 正規表示式:a.*b,它將會匹配最長的以 a 開始,以 b 結束的字串。如果用它來搜尋 aabab 的話,它會匹配整個字串 aabab,這被稱為 -------貪婪匹配
  • -
  • 我們更需要 懶惰匹配,也就是匹配儘可能少的字元,前面給出的量詞都可以被轉化為 懶惰匹配模式, 只要在它後面加一個問號 ? 。這樣 .*? 就意味著匹配任意數量的重複,但是在能使整個 匹配成功的前提下使用最少的重複
  • a.*?b 匹配最短的,以 a 開始, 以 b 結束的字串。如果把它應用於 aabab 的話,它會匹配 aabab

總結:

貪婪與懶惰模式之間的區別就在於:懶惰模式 在量詞 * 的後面多了一個 問號 ?

高階5 - 模式匹配的優先順序

在使用正規表示式時,需要注意匹配的順序。通常相同優先順序 從左到右 進行計算,不同優先順序的運算 先高後低。各種操作符的匹配順序優先順序 從高到低 如下表所示。

順序元字元描述
1跳脫字元
2()(?:)(?=)[]模式單元和原子表
3*+{n}{n,}{n,m}重複匹配
4^$bBAZ邊界限制
5|模式選擇

範例

1. 字元跳脫

1問:要匹配字串 333333$3333333 中的 $ 正則應該怎麼寫?
2問:如果在 PHP 中 preg_match 函數分別用單引號雙引號的表示式來匹配上面的 $,怎麼寫?

答案:

  • 表示式需要的規則是 $
  • 用單引號表示上面的字串 '/$/'。(為方便檢視我們拆分一下為 '/ $/'
  • 用雙引號表示上面的字串 "/$/"。(為方便檢視我們拆分一下為 "/ $/"
  • 問什麼呢?

再答:

  1. PHP 中單引號不跳脫任何字元,但是唯獨跳脫 ,所以我們需要 6個 來生成表示式。
  2. 雙引號除了跳脫 以外,還需要多一個 用來跳脫 $ 所以它 需要 7 個

相關教學推薦:PHP視訊教學

以上就是詳解正規表示式的詳細內容,更多請關注TW511.COM其它相關文章!