正規表示式 - 範例


簡單表達式

正規表示式的最簡單形式是在搜尋字串中匹配其本身的單一普通字元。例如,單字元模式,如 A,不論出現在搜尋字串中的何處,它總是符合字母 A。以下是一些單字元正規表示式模式的範例:

/a/
/7/
/M/

可以將許多單字元組合起來以形成大的表達式。例如,下列正規表示式組合了單字元表達式:a、7 和 M。

/a7M/

請注意,沒有串連運算子。只須在一個字元後面鍵入另一個字元。

字元符合

句點 (.) 符合字串中的各種列印或非列印字符,只有一個字元例外。這個例外就是換行符號 (\n)。下面的正規表示式符合aac、abc、acc、adc 等等,以及a1c、a2c、a-c 和a#c:

/a.c/

若要符合包含檔名的字串,而句點(.) 是輸入字串的組成部分,請在正規表示式中的句點前面加反斜扛(\) 字元。舉例來說明,下面的正規表示式符合 filename.ext:

/filename\.ext/

這些表達式只讓您匹配"任何"單一字元。可能需要匹配清單中的特定字元組。例如,可能需要尋找用數字表示的章節標題(Chapter 1、Chapter 2 等等)。

中括號表達式

若要建立符合字元組的一個列表,請在方括號([ 和 ])內放置一個或更多單一字元。當字元括在中括號內時,此列表稱為"中括號表達式"。與在任何別的位置一樣,普通字元在中括號內表示其本身,即,它在輸入文字中匹配一次其本身。大多數特殊字元在中括號表達式內出現時失去它們的意義。不過也有一些例外,如:

  • 如果 ] 字元不是第一項,它結束一個清單。若要匹配清單中的 ] 字符,請將它放在第一位,緊跟在開始 [ 後面。

  • \ 字元繼續作為轉義符。若要匹配 \ 字符,請使用 \\。

括在中括號表達式中的字元只符合處於正規表示式中該位置的單一字元。以下正規表示式符合 Chapter 1、Chapter 2、Chapter 3、Chapter 4 和 Chapter 5:

/Chapter [12345]/

請注意,單字 Chapter 和後面的空格的位置相對於中括號內的字元是固定的。中括號表達式指定的只是匹配緊跟在單字 Chapter 和空格後面的單字位置的字元集。這是第九個字元位置。

若要使用範圍取代字元本身來表示符合字元組,請使用連字號 (-) 將範圍中的開始字元和結束字元分開。單一字元的字元值決定範圍內的相對順序。下面的正規表示式包含範圍表達式,該範圍表達式等效於上面顯示的中括號中的列表。

/Chapter [1-5]/

當以這種方式指定範圍時,開始值和結束值兩者都包含在範圍內。注意,還有一點很重要,按 Unicode 排序順序,開始值必須在結束值的前面。

若要在中括號表達式中包含連字符,請採用下列方法之一:

  • 用反斜扛將它轉義:

    [\-]
  • 將連字符放在中括號列表的開始或結尾。下面的表達式匹配所有小寫字母和連字符:

    [-a-z]
    [a-z-]
  • 建立一個範圍,在該範圍中,開始字符值小於連字符,而結束字符值等於或大於連字符。下面的兩個正規表示式都符合此要求:

    [!--]
    [!-~]

若要尋找不在清單或範圍內的所有字符,請將插入符號(^) 放在清單的開頭。如果插入字元出現在清單中的其他任何位置,則它會匹配其本身。下面的正規表示式符合1、2、3、4 或5 以外的任何數字和字元:

/Chapter [^12345]/

在上面的範例中,表達式在第九個位置匹配1、2、3、 4 或5 之外的任何數字和字元。這樣,例如,Chapter 7 就是一個匹配項,Chapter 9 也是一個匹配項。

上面的表達式可以使用連字號 (-) 來表示:

/Chapter [^1-5]/

中括號表達式的典型用途是指定任何大寫或小寫字母或任何數字的匹配。下面的表達式指定這樣的匹配:

/[A-Za-z0-9]/

替換和分組

替換使用 | 字元來允許在兩個或多個替換選項之間進行選擇。例如,可以擴充章節標題正規表示式,以傳回比章標題範圍更廣的符合項。但是,這並不像您可能認為的那樣簡單。替換匹配 | 字元任一側最大的表達式。

您可能認為,下面的表達式匹配出現在行首和行尾、後面跟一個或兩個數字的Chapter 或Section:

/^Chapter|Section [1-9][0-9]{0,1}$/

很遺憾,上面的正規表示式要麼符合行首的單字Chapter,要麼匹配行尾的單字Section 及跟在其後的任何數字。如果輸入字串是 Chapter 22,那麼上面的表達式只會符合單字 Chapter。如果輸入字串是 Section 22,那麼該表達式會比對 Section 22。

若要讓正規表示式更容易控制,可以使用括號來限制替換的範圍,即,確保它只應用於兩個單字 Chapter 和 Section。但是,括號也用於創建子表達式,並可能捕獲它們以供以後使用,這一點在有關反向引用的那一節中講述。透過在上面的正規表示式的適當位置加上括號,就可以使該正規表示式符合 Chapter 1 或 Section 3。

下面的正規表示式使用括號來組合Chapter 和Section,以便表達式正確地起作用:

/^(Chapter|Section) [1-9][0-9]{0,1}$/

儘管這些表達式正常工作,但Chapter|Section 周圍的括號還將捕獲兩個匹配字中的任一個以供以後使用。由於在上面的表達式中只有一組括號,因此,只有一個被捕獲的"子匹配項"。

在上面的範例中,您只需要使用括號來組合單字 Chapter 和 Section 之間的選擇。若要防止匹配被保存以備將來使用,請在括號內正規表示式模式之前放置 ?:。下面的修改提供相同的能力而不保存子匹配項:

/^(?:Chapter|Section) [1-9][0-9]{0,1}$/

除 ?: 元字元外,兩個其他非捕獲元字元創建被稱為"預測先行"匹配的某些內容。正向預測先行使用 ?= 指定,它會符合處於括號中符合正規表示式模式的起始點的搜尋字串。反向預測先行使用 ?! 指定,它會符合處於與正規表示式模式不符的字串的起始點的搜尋字串。

例如,假設您有一個文檔,該文檔包含指向 Windows 3.1、Windows 95、Windows 98 和 Windows NT 的參考。再進一步假設,您需要更新該文檔,並將指向 Windows 95、Windows 98 和 Windows NT 的所有參考變更為 Windows 2000。下面的正規表示式(這是一個正向預測先行的範例)符合Windows 95、Windows 98 和Windows NT:

/Windows(?=95 |98 |NT )/

找到一個符合後,緊接著就在符合的文字(不包含預測先行中的字元)之後搜尋下一個符合。例如,如果上面的表達式符合 Windows 98,將在 Windows 之後而不是在 98 之後繼續搜尋。

其他範例

下面列出一些正規表示式範例:

正規表示式描述
/\b([a-z]+) \1\b/gi#一個單字連續出現的位置。
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/將一個URL解析為協定、網域、連接埠及相對路徑。
/^(?:Chapter|Section) [1-9][0-9]{0,1}$/定位章節的位置。
/[-a-z]/A至z共26個字母再加一個-號。
/ter\b/可符合chapter,而不能符合terminal。
/\Bapt/可符合chapter,而不能符合aptitude。
/Windows(?=95 |98 |NT )/#可符合Windows95或Windows98或WindowsNT,當找到一個符合後,從Windows後面開始進行下一次的檢索匹配。
/^\s*$/#符合空白行。
/\d{2}-\d{5}/#驗證由兩個數字、一個連字號再加 5 位數組成的 ID 號碼。
/<\s*(\S+)(\s[^>]*)?>[\s\S]*<\s*\/\ 1\s*>/符合HTML 標記。
#