範例 |
正規表示式範例 |
數字範圍 |
浮點數 |
電子郵件地址 |
IP 位址 |
有效日期 |
數字日期轉文字 |
信用卡號碼 |
符合完整行 |
刪除重複行 |
程式設計 |
兩個相近的字 |
陷阱 |
災難性回溯 |
重複太多次 |
阻斷服務 |
讓所有內容都變成可選 |
重複擷取群組 |
混合 Unicode 和 8 位元 |
此網站上的更多資訊 |
簡介 |
正規表示式快速入門 |
正規表示式教學 |
替換字串教學 |
應用程式和語言 |
正規表示式範例 |
正規表示式參考 |
替換字串參考 |
書籍評論 |
可列印 PDF |
關於此網站 |
RSS Feed 和部落格 |
正規表示式非常有用,可讓您在文字編輯器中操作原始碼或在基於 regex 的文字處理工具中操作原始碼。大多數程式設計語言都使用類似的結構,例如關鍵字、註解和字串。但通常有一些細微的差異,使得難以使用正確的 regex。在從下列範例清單中挑選 regex 時,務必閱讀每個 regex 的說明,以確保您挑選正確的 regex。
除非另有說明,否則下列所有範例都假設點不會符合換行符號,而插入符號和美元符號會在內嵌換行符號處符合。在許多程式設計語言中,這表示單行模式必須關閉,而多行模式必須開啟。
當單獨使用時,這些正規表示式可能無法達到預期的結果。如果註解出現在字串內,註解正規表示式會將字串內的文字視為註解。字串正規表示式也會比對註解內的字串。解決方案是使用多個正規表示式,並將它們組合成一個簡單的剖析器,如下面的偽程式碼所示
GlobalStartPosition := 0;
while GlobalStartPosition < LengthOfText do
GlobalMatchPosition := LengthOfText;
MatchedRegEx := NULL;
foreach RegEx in RegExList do
RegEx.StartPosition := GlobalStartPosition;
if RegEx.Match and RegEx.MatchPosition < GlobalMatchPosition then
MatchedRegEx := RegEx;
GlobalMatchPosition := RegEx.MatchPosition;
endif
endforeach
if MatchedRegEx <> NULL then
// At this point, MatchedRegEx indicates which regex matched
// and you can do whatever processing you want depending on
// which regex actually matched.
endif
GlobalStartPosition := GlobalMatchPosition;
endwhile
如果您將比對註解的正規表示式和比對字串的正規表示式放入 RegExList 中,那麼您可以確定註解正規表示式不會比對字串內的註解,反之亦然。在迴圈內,您可以根據是否為註解或字串來處理比對結果。
另一種解決方案是組合正規表示式: (註解)|(字串)。 交替 的效果與上述程式碼片段相同。反覆處理此正規表示式的所有比對結果。在迴圈內,檢查哪個擷取群組找到正規表示式比對結果。如果群組 1 匹配,則您有一個註解。如果群組 2 匹配,則您有一個字串。然後根據該結果處理比對結果。
您可以使用此技術建立一個完整的剖析器。針對您要剖析的語言或檔案格式中的所有詞彙元素加入正規表示式。在迴圈內,追蹤比對的內容,以便可以根據其內容處理後續比對結果。例如,如果需要平衡大括號,則在比對到左大括號時增加計數器,在比對到右大括號時減少計數器。如果計數器在任何時間點變為負數,或在到達檔案結尾時仍不為零,則會產生錯誤。
#.*$ 比對從 # 開始並持續到 行尾 的單行註解。類似地,//.*$ 比對從 // 開始的單行註解。
如果註解必須出現在 行首,請使用 ^#.*$。如果行首與註解之間只允許有 空白,請使用 ^\s*#.*$。C 中的編譯器指令或實用程式碼可透過這種方式進行比對。請注意,在最後一個範例中,任何前導空白都會是正規表示式比對的一部分。請使用 擷取括號 來區分空白和註解。
/\*.*?\*/ 會比對 C 式多行註解,前提是您已開啟 點號 比對換行符的選項。一般語法為 begin.*?end。C 式註解不允許巢狀。如果「begin」部分出現在註解內,則會被忽略。一旦找到「end」部分,註解就會關閉。
如果您的程式語言允許巢狀註解,則沒有直接的方法可以使用正規表示式比對它們,因為正規表示式無法計數。需要額外的邏輯。
"[^"\r\n]*" 會比對單行字串,不允許引號字元出現在字串內。使用 否定字元類別 比使用惰性點號更有效率。 "[^"]*" 允許字串跨多行。
"[^"\\\r\n]*(?:\\.[^"\\\r\n]*)*" 符合單行字串,其中引號字元若以反斜線跳脫,則可以出現。儘管此正規表示式看起來比實際上複雜,但它比更簡單的解法快很多,因為如果雙引號單獨出現,而非字串的一部分,則這些解法會導致大量回溯。 "[^"\\]*(?:\\.[^"\\]*)*" 允許字串橫跨多行。
您可以調整上述正規表示式,以符合由兩個(可能不同)字元分隔的任何順序。如果我們使用 b 作為起始字元、e 作為結束字元,以及 x 作為跳脫字元,則不含跳脫的版本會變成 b[^e\r\n]*e,而含跳脫的版本會變成 b[^ex\r\n]*(?:x.[^ex\r\n]*)*e。
\b\d+\b 符合正整數。別忘了 字首字尾界線! [-+]?\b\d+\b 允許符號。
\b0[xX][0-9a-fA-F]+\b 符合 C 式十六進位數字。
((\b[0-9]+)?\.)?[0-9]+\b 符合整數以及包含可選整數部分的浮點數。 (\b[0-9]+\.([0-9]+\b)?|\.[0-9]+\b) 符合包含可選整數以及可選小數部分的浮點數,但不符合整數。
((\b[0-9]+)?\.)?\b[0-9]+([eE][-+]?[0-9]+)?\b 符合科學記號的數字。尾數可以是整數或包含可選整數部分的浮點數。指數為可選。
\b[0-9]+(\.[0-9]+)?(e[+-]?[0-9]+)?\b 也比對科學記號中的數字。與前一個範例的不同在於,如果尾數是小數點數字,整數部分是強制性的。
如果您讀過 浮點數範例,您會注意到上述正規表示式與其中使用的不同。上述正規表示式較為嚴格。它們使用字元邊界來排除屬於其他部分的數字,例如識別碼。您可以在上述所有正規表示式之前加上 [-+]?,以在正規表示式中包含一個可選符號。我沒有在上面這樣做,因為在程式語言中,+ 和 - 通常被視為運算子,而不是符號。
比對保留字很簡單。只要使用 交替 將它們串在一起: \b(first|second|third|etc)\b 再一次,不要忘記 字元邊界。
| 快速入門 | 教學 | 工具與語言 | 範例 | 參考 | 書籍評論 |
| 正規表示式範例 | 數字範圍 | 浮點數 | 電子郵件地址 | IP 地址 | 有效日期 | 數字日期轉文字 | 信用卡號碼 | 比對完整行 | 刪除重複行 | 程式設計 | 兩個相近的字 |
| 災難性的回溯 | 過多重複 | 拒絕服務 | 讓所有內容都可選 | 重複擷取群組 | 混合 Unicode 和 8 位元 |
頁面網址: https://regular-expressions.dev.org.tw/examplesprogrammer.html
頁面最後更新:2019 年 11 月 22 日
網站最後更新:2024 年 3 月 15 日
版權所有 © 2003-2024 Jan Goyvaerts。保留所有權利。