快速入門
教學
工具和語言
範例
參考
書籍評論
Regex 教學
簡介
目錄
特殊字元
不可列印字元
Regex 引擎內部
字元類別
字元類別減法
字元類別交集
簡寫字元類別
錨點
字詞界線
交替
選用項目
重複
群組和擷取
反向參照
反向參照,第 2 部分
命名群組
相對反向參照
分支重設群組
自由間距和註解
Unicode
模式修改器
原子群組
獨佔量詞
前瞻和後顧
環顧,第 2 部分
將文字保留在比對之外
條件
平衡群組
遞迴
子常式
無限遞迴
遞迴和量詞
遞迴和擷取
遞迴和反向參照
遞迴和回溯
POSIX 方括號表示式
零長度比對
持續比對
本網站的更多資訊
簡介
正規表示式快速入門
正規表示式教學
替換字串教學
應用程式和語言
正規表示式範例
正規表示式參考
替換字串參考
書籍評論
可列印 PDF
關於本網站
RSS 摘要和部落格
RegexBuddy—Better than a regular expression tutorial!

字串開頭和結尾錨點

到目前為止,我們已經瞭解了 字面字元字元類別。在 regex 中放入其中一個會告訴 regex 引擎嘗試比對單一字元。

錨點是不同的種類。它們根本不會比對任何字元。相反地,它們會比對字元之前、之後或之間的位置。它們可用於將 regex 比對「錨定」在特定位置。插入符號 ^ 會比對字串中第一個字元之前的字元。將 ^a 套用至 abc 會比對 a^b 根本不會比對 abc,因為 b 無法在字串開頭(由 ^ 比對)的正後方比對。請參閱下方 regex 引擎的內部檢視。

類似地,$ 會比對字串中最後一個字元的正後方。 c$ 會在 abc 中比對 c,而 a$ 則完全不會比對。

僅由錨點組成的正規表示式只能找到零長度比對。這可能很有用,但也會產生複雜性,這在教學課程的最後會說明。

有用的應用

在程式語言中使用正規表示式來驗證使用者輸入時,使用錨點非常重要。如果您在Perl指令碼中使用程式碼if ($input =~ m/\d+/)來查看使用者是否輸入整數,即使使用者輸入qsdf4ghjk,它也會接受輸入,因為\d+比對4。要使用的正確正規表示式是^\d+$。因為在比對\d+之前必須比對「字串開頭」,並且在比對之後必須比對「字串結尾」,因此整個字串必須由數字組成才能比對^\d+$

使用者很容易意外輸入空格。當Perl從文字檔讀取一行時,換行也會儲存在變數中。因此在驗證輸入之前,最好先修剪前導和尾隨空白^\s+比對前導空白,而\s+$比對尾隨空白。在Perl中,您可以使用$input =~ s/^\s+|\s+$//g。靈活使用交替和/g讓我們能夠在單一行程式碼中執行此操作。

使用^和$作為行開頭和行結尾錨點

如果您有一個由多行組成的字串,例如first line\nsecond line(其中\n表示換行),通常需要處理各行,而不是整個字串。因此,本教學課程中討論的大多數正規表示式引擎都有選項可以擴充兩個錨點的意義。^然後可以在字串開頭(在上述字串中的f之前)以及每個換行符號之後(在\ns之間)比對。同樣地,$仍然比對字串結尾(在最後一個e之後),以及每個換行符號之前(在e\n之間)。

在文字編輯器(例如EditPad Pro或GNU Emacs)和正規表示式工具(例如PowerGREP)中,插入符號和美元符號始終比對每行的開頭和結尾。這是合理的,因為這些應用程式設計為處理整個檔案,而不是短字串。在Rubystd::regex中,插入符號和美元符號也始終比對每行的開頭和結尾。在Boost中,它們預設比對每行的開頭和結尾。使用ECMAScript語法時,Boost允許您使用regex_constants::no_mod_m關閉此功能。

在這個網站上討論的所有其他程式語言和函式庫中,你必須明確啟用此延伸功能。它傳統上稱為「多行模式」。在 Perl 中,你可以透過在正規表示式代碼後加上 m 來執行此操作,如下所示:m/^regex$/m;。在 .NET 中,當你指定 RegexOptions.Multiline 時,錨點會在換行符號前後比對,例如 Regex.Match("string", "regex", RegexOptions.Multiline)

換行字元

關於點的教學頁面已經討論過哪些字元被各種正規表示式風格視為 換行字元。這會在多行模式中對錨點產生同樣的影響,以及當美元符號在最後一個換行的結尾之前比對時。錨點處理由單一字元組成的換行符號的方式與每個正規表示式風格中的點相同。

對於錨點來說,當 CR 和 LF 成對出現且正規表示式風格將這兩個字元都視為換行符號時,還需要額外考量。 DelphiJavaJGsoft 風格 將 CRLF 視為不可分割的成對字元。 ^ 會在 CRLF 之後比對,而 $ 會在 CRLF 之前比對,但兩者都不會在 CRLF 成對字元的中間比對。 JavaScriptXPath 將 CRLF 成對字元視為兩個換行符號。 ^ 會在 CRLF 的中間和之後比對,而 $ 會在 CRLF 之前和中間比對。

字串的永久開頭和結尾錨點

\A 僅會在字串的開頭比對。同樣地,\Z 僅會在字串的結尾比對。這兩個代幣絕不會在換行符號中比對。這是本教學課程中討論的所有正規表示式風格中的情況,即使你開啟「多行模式」也是如此。在 EditPad Pro 和 PowerGREP 中,插入符號和美元符號始終會在行的開頭和結尾比對,\A\Z 僅會在整個檔案的開頭和結尾比對。

JavaScriptPOSIXXMLXPath 不支援 \A\Z。你只能使用插入符號和美元符號來執行此目的。

POSIX 正則表示式的 GNU 擴充 使用 \`(反引號)來比對字串的開頭,並使用 \'(單引號)來比對字串的結尾。

以換行符號結尾的字串

由於 Perl 在從檔案中讀取一行時會回傳一個結尾有換行符號的字串,因此 Perl 的正則表示式引擎會比對 $ 在字串結尾換行符號前的位置,即使已關閉多行模式。Perl 也會比對字串最結尾的 $,無論該字元是否為換行符號。因此 ^\d+$ 會比對 123,無論主旨字串是 123123\n

大多數現代的正則表示式風格都複製了此行為。其中包括 .NETJavaPCREDelphiPHPPython。此行為與「多行模式」等任何設定無關。

在除了 Python 之外的所有這些風格中,\Z 也會比對最後一個換行符號之前的位置。如果您只想要比對字串最結尾的位置,請使用 \z(小寫 z,而非大寫 Z)。\A\d+\z 不會比對 123\n\z 會比對換行符號之後的位置,而 簡寫字元類別 沒有比對換行符號。

在 Python 中,\Z 僅比對字串最結尾的位置。Python 不支援 \z

以多個換行符號結尾的字串

如果一個字串以多個換行符號結尾,且多行模式已關閉,則 $ 僅會比對在所有可以比對最後一個換行符號之前的位置。對於 \Z 也是如此,與多行模式無關。

Boost 是唯一的例外。在 Boost 中,\Z 可以比對任何數量的尾端換行符號之前的位置,以及字串最結尾的位置。因此,如果主旨字串以三個換行符號結尾,Boost 的 \Z 有四個位置可以比對。與其他所有風格一樣,Boost 的 \Z 與多行模式無關。Boost 的 $ 僅會在您關閉多行模式時比對字串最結尾的位置(在 Boost 中預設為開啟)。

深入了解正則表示式引擎

讓我們看看當我們嘗試將 ^4$749\n486\n4 (其中 \n 代表換行字元) 相符於多行模式時會發生什麼事。一如往常,正規表示式引擎從第一個字元開始:7。正規表示式中的第一個代碼為 ^。由於這個代碼為零長度代碼,引擎不會嘗試將它與字元相符,而是與正規表示式引擎迄今為止已達到的字元之前的位置相符。^ 確實與 7 之前的位置相符。引擎接著進展到下一個正規表示式代碼:4。由於前一個代碼為零長度,正規表示式引擎不會進展到字串中的下一個字元。它仍然停留在 74 是字面字元,與 7 不相符。正規表示式沒有其他排列組合,因此引擎從第一個正規表示式代碼重新開始,在下一字元:4。這次,^ 無法與 4 之前的位置相符。這個位置之前有一個字元,而且那個字元不是換行。引擎繼續進行到 9,並再次失敗。下一次嘗試,在 \n,也失敗了。同樣地,\n 之前的位置之前有一個字元,9,而且那個字元不是換行。

接著,正規表示式引擎會到達字串中的第二個 4。由於 ^ 前面有換行字元,因此它可以在 4 前面的位置進行比對。正規表示式引擎再次前進到下一個正規表示式符號 4,但不會前進字串中的字元位置。4 會比對 4,而引擎會同時前進正規表示式符號和字串字元。現在,引擎會嘗試在 8 前面的位置(確實:在前面)比對 $。由於這個位置後面有字元,而且該字元不是換行字元,因此美元符號無法在此進行比對。

引擎必須再次嘗試比對第一個符號。先前,它已成功在第二個 4 進行比對,因此引擎會繼續在下一字元 8 進行比對,而插入符號不會進行比對。在 6 和換行字元中也是一樣。

最後,正規表示式引擎會嘗試在字串中的第三個 4 比對第一個符號。成功。之後,引擎會成功地將 44 進行比對。目前的正規表示式符號會前進到 $,而目前的字元會前進到字串中的最後一個位置:字串後的空白。沒有任何需要字元才能進行比對的正規表示式符號可以在此進行比對。甚至連 否定字元類別 都無法進行比對。不過,我們嘗試比對的是美元符號,而強大的美元符號是個奇怪的野獸。它的長度為零,因此它會嘗試比對目前字元前面的位置。這個「字元」是字串後的空白並無所謂。事實上,美元符號會檢查目前的字元。它必須是換行字元或字串後的空白,才能讓 $ 比對目前字元前面的位置。由於範例中是這種情況,因此美元符號成功進行比對。

由於 $ 是正規表示式中的最後一個符號,因此引擎已找到成功的比對:字串中的最後一個 4