正規表示式 (Regular Expression) 語法整理

正規表示式 (Regular Expression, 簡寫 regex、regexp 或 RE),又稱正則表達式、正規表示法、規則運算式、常規表示法 (Wiki)。

在字串的處理上,針對大量、重複、有固定邏輯的文字,那「正規表示式」是非常 Powerful 的工具! 即便不是程式設計師,在可以運用到「正規表示式」的場合 (例如: 文字編輯器),也可以幫你節省許多文字處理的時間。

但是在初學者的眼中,正規表示式卻又像是天書一樣的難以理解。以下文章僅針對正規表示式的相關語法做解說,初學者可以撘配本站轉載的文章「PHP 正規表示式基本語法」去理解,再進入線上測試工具,以實際的例子去做測試。

語法整理 (Pattern)

字元符號

  • .: 任意文字、數字及符號,但不包括換行
  • \d: 任意數字
  • \w: 任意文字、數字或底線
  • \s: 任意空白字元,包含空白、定位、換行字元 (同 [ \t\n])
  • \D: 任意非數字
  • \W: 任意非文字、數字或底線
  • \S: 任意非空白字元 (同 [^ \t\n])
  • \n: 換行字元
  • \t: 定位字元
  • \OCT: 八進制字元,ex: \101 = "A"
  • \xHEX: 十六進制字元,ex: \x41 = "A"
  • \uUnicode: Unicode 字元,ex: \u4F60 = "你"。
    另外,Unicode 中文範圍: [\u4E00-\u9FA5],中日韓文字範圍: [\u4E00-\u9FFF]
  • \: 不轉譯控制符號

一般狀態下,字元符號都不包括換行字元 (\n),因此遇到「換行」就會停止比對。在某些環境下可以啟用多行模式 (Multiline),則換行字元 (\n) 會被視為一般文字。

字元列舉

列舉的原則:

  1. 放在中括號 [ ... ] 裡的字元皆為單獨比對的字元
  2. 在中括號內加 ^ 表示「反向列舉」
  3. 可以用 - 來代表連續的字元範圍

範例:

  • [0123456789]: 任意數字 (同 \d)
  • [0-9]: 任意數字,同 (同 \d)
  • [a-z]: 任意小寫英文字母
  • [a-zA-Z]: 任意大小寫的英文字母
  • [0-9a-zA-Z]: 任意數字、英文字母
  • [^x]: 反向列舉,任意非 x 的字元
  • [^0-9]: 反向列舉,任意非數字 (同 \D)

字串列舉

  • |: 或

次數符號

  • *: 重複 0 次以上 (同 {0,}) *貪婪原則
  • +: 重複 1 次以上 (同 {1,}) *貪婪原則
  • ?: 重複 0 或 1 次 (同 {0,1}) *貪婪原則
  • {n}: 重覆 n 次
  • {n,}: 重覆 n 次以上 *貪婪原則
  • {0,n}: 重覆 0 ~ n 次 *貪婪原則
  • {n,m}: 重覆 n ~ m 次 *貪婪原則

說明:

  1. 所有的「次數符號」都會極大化 (Infinite) 要比對的範圍,稱為「貪婪原則」。
    ex: .*\d+ 因為貪婪原則,前面的 .* 就已經涵蓋後面的 \d+ 所要比對的數字了,因此 \d+ 在這裡是多餘的!
  2. 如果要取消「貪婪原則」,只要在次數符號的後面加上 ? 即可讓它節制一點、不要那麼的貪婪,讓放在後面的比對規則也可以有作用。
  3. 在實務上,我們不太會將 *? 這兩個次數符號放在正規表示式的最後,因為它們兩者都允許「重覆 0 次」,因為比對之後可能會多出「空白」的結果。

邊界符號

  • ^: 要在行的開頭 (Start of line)
  • $: 要在行的結尾 (End of line)
  • \b: 必須是字串 (文字、數字、底線) 的開頭或結尾
  • \B: 不能是字串 (文字、數字、底線) 的開頭或結尾

進階

群組

  1. 可以使用小括號 ( ... ) 將既有的規則組合成一個「群組」
  2. 建立規則群組之後,可再以此群組為基礎,套用其它的規則
  3. 可以用 \1 ... \9 來代表前面符合的群組
  4. 當要儲存或取代比對的內容時,可以用 $1 .. $9 (或 \1 ... \9) 來代表各群組

判斷式

右合、正看 (Lookahead):

  1. Pattern1(?:Pattern2): 符合 Pattern1 並且右方符合 Pattern2 才算符合全部的 Pattern
    ex: Windows(?:95|98|2000) 可符合 Windows95,但不符合 WindowsNT
  2. Pattern1(?=Pattern2): 符合 Pattern1 並且右方符合 Pattern2 才算符合 Pattern1
    白話文: 我要找 Pattern1,其右方必須為 Pattern2
    ex: Windows(?=95|98|2000) 可符合 Windows95 的 Windows,但不符合 WindowsNT 的 Windows
  3. Pattern1(?!Pattern2): 符合 Pattern1 但右方不符合 Pattern2 才算符合 Pattern1
    白話文: 我要找 Pattern1,但右方不能為 Pattern2
    ex: Windows(?!95|98|2000) 可符合 Widnows 或 WindowsNT 的 Windows,但不符合 Windows95 的 Windows

左合、回頭看 (Lookbehind):

  1. (?<=Pattern1)Pattern2: 符合 Pattern2 並且左方符合 Pattern1 才算符合 Pattern2
    白話文: 我要找 Pattern2,其左方必須為 Pattern1
    ex: (?<=Chapter|Section)[\d]+ 可符合 Chapter15 的 15,但不符合 Topic15 的 15
  2. (?<!Pattern1)Pattern2: 符合 Pattern2 但左方不符合 Pattern1 才算符合 Pattern2
    白話文: 我要找 Pattern2,但左方不能為 Pattern1
    ex: (?<!Chapter|Section)(?<!\d)[\d]+ 可符合 Topic15 的 15,但不符合 Chapter15 的 15

說明:

  1. 以上判斷式的小括號 (? ... ) 並不會成為「群組」
  2. 並非所有的環境都能完整支援判斷式的用法

線上測試

  1. Regular Expressions 101
  2. RegEx Testing
  3. 正規表示式線上測試-站長工具
  4. Regulex: JavaScript Regular Expression Visualizer - 將正規表示式圖形化
  5. Regexper - 將正規表示式圖形化

參考網頁

  1. 正規表示式 - 維基百科,自由的百科全書
  2. [轉載]PHP 正規表示式基本語法
  1. No comments yet.

  1. No trackbacks yet.

return top

%d 位部落客按了讚: