正規表示式 133 例
從寫法本身,到電子郵件、日期、位址的檢查。每個式子都配了該符合的例子和不該符合的例子,而且測試每次都真的跑一遍。
寫法28
規定怎樣指向單個字元的寫法。其餘一切都從這裡開始。
\d一個數字\D數字以外的任何字元\w字母、數字或底線\W不是單詞字元的任何東西\s一個空白字元\S空白以外的任何字元^.$任意一個字元^[a-z]+$只要英文小寫字母^[A-Z]+$只要英文大寫字母^[A-Za-z0-9]+$只要字母和數字^[^0-9]+$一個數字都沒有的文字^[가-힣]+$只要諺文^[ぁ-んァ-ヶー]+$只要假名^[\u4e00-\u9fff]+$只要漢字^a\.b$點號本身^a/b$斜線本身\t一個定位字元\n一個換行字元\r\nWindows 式的換行^\u00e9$用碼位寫出的字元^Hello以這個詞開頭的文字world$以這個詞結尾的文字^cat$正好只有這個詞,別無他物\bcat\b獨立成詞的位置,不在別的詞裡\Bcat只在別的詞內部的位置^cat$不分大小寫的比對^b每一行的開頭,不只是整段的開頭^a.b$任意字元,連換行也算重複與分組17
規定重複多少次,以及把哪一段看作一個整體。
^ab*c$零次或多次^ab+c$一次或多次^colou?r$可有可無的一個字母^\d{4}$正好四位數字^\d{2,4}$兩位到四位數字^\d{2,}$兩位以上的數字<.+?>盡量短地取一個標籤^<.+>$盡量長地取一整塊^(?:cat|dog)$兩個詞裡的任意一個^(?:ab)+$兩個字母一組,重複出現^(\d{3})-(\d{4})$前後兩段分別抓出來^(?:\d{3}-)+\d{4}$只分組,不擷取^(?<year>\d{4})-(?<month>\d{2})$取個名字再擷取(\w)\1同一個字元連著出現兩次\b(\w+)\s+\1\b同一個詞打了兩遍^(?:https?://)?example\.com$帶不帶協定開頭都行的網址^(?:\d{1,3}\.){3}\d{1,3}$由四段組成的位址前後查看8
只查看前後有什麼,並不把它吃掉。疊加條件時用得上。
整串檢查44
兩端都錨住,整個字串合上才算通過。輸入檢查用的就是這類。
^[^\s@]+@[^\s@.]+(?:\.[^\s@.]+)+$一個電子郵件位址^https?://[^\s/$.?#][^\s]*$一個網址^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$一個網域名稱^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$一個 IPv4 位址^(?:[0-9a-f]{1,4}:){7}[0-9a-f]{1,4}$不省略寫全的 IPv6 位址^(?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2}$一個 MAC 位址^(?:6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]?\d{1,4})$一個連接埠號^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$一個 UUID^#(?:[0-9a-f]{3}|[0-9a-f]{6})$十六進位色碼^rgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)$rgb() 形式的色彩值^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$ISO 格式的日期^(?:0[1-9]|[12]\d|3[01])/(?:0[1-9]|1[0-2])/\d{4}$用斜線寫的日期^(?:[01]\d|2[0-3]):[0-5]\d$24 小時制的時刻^(?:0?[1-9]|1[0-2]):[0-5]\d\s?(?:am|pm)$帶 am/pm 的時刻^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$完整的 ISO 時間戳記^P(?=\d|T\d)(?:\d+Y)?(?:\d+M)?(?:\d+D)?(?:T(?:\d+H)?(?:\d+M)?(?:\d+S)?)?$ISO 格式的時間長度^\d+\.\d+\.\d+(?:-[0-9a-z.-]+)?(?:\+[0-9a-z.-]+)?$語意化版本號^\d+$不帶符號的整數^[+-]?\d+$可以帶符號的整數^-?\d+(?:\.\d+)?$可以帶小數部分的數^-?\d+(?:\.\d+)?[eE][+-]?\d+$用科學記數法寫的數^(?:100(?:\.0+)?|\d{1,2}(?:\.\d+)?)%$0 到 100 之間的百分比^\d{1,3}(?:,\d{3})*$每三位打一個逗號的數^[$€£¥₩]\s?\d{1,3}(?:,\d{3})*(?:\.\d{2})?$帶貨幣符號的金額^[0-9a-f]+$十六進位字串^[01]+$只由 0 和 1 組成的字串^[0-7]+$八進位字串^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$base64 編碼的字串^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*$由兩個點分成三段的 JWT^\+[1-9]\d{7,14}$國際標準格式的電話號碼^[a-z][a-z0-9_]{2,15}$以字母開頭的使用者名稱^[a-z0-9]+(?:-[a-z0-9]+)*$用在網址裡的連字詞^[^\\/:*?"<>|]+\.[a-z0-9]+$帶副檔名的檔名^.+\.(?:jpe?g|png|gif|webp|avif|svg)$圖片檔案的副檔名^/(?:[^/\0]+/)*[^/\0]*$Unix 風格的路徑^[A-Za-z]:\\(?:[^\\/:*?"<>|]+\\)*[^\\/:*?"<>|]*$Windows 路徑^</?[a-z][a-z0-9]*(?:\s[^<>]*)?/?>$單個 HTML 標籤^\.-?[_a-z][_a-z0-9-]*$CSS 類別選擇器^M{0,3}(?:CM|CD|D?C{0,3})(?:XC|XL|L?X{0,3})(?:IX|IV|V?I{0,3})$羅馬數字^-?(?:90(?:\.0+)?|[1-8]?\d(?:\.\d+)?)$緯度值^-?(?:180(?:\.0+)?|1[0-7]\d(?:\.\d+)?|\d{1,2}(?:\.\d+)?)$經度值^(?:0|[1-9]\d*)$開頭不帶 0 的數^\d*[02468]$偶數^\s*$一行空白擷取與清理36
用來從一段文字裡只挑出、或只刪掉需要的那部分。
\s+$行尾留下的空格^\s+行首的空格^\s+|\s+$前後兩端的空格\s{2,}連著兩個以上的空格\n\s*\n兩行之間的空行\D+不是數字的部分[^\x00-\x7F]ASCII 之外的字元[\x00-\x1F]看不見的控制字元</?[^>]+>文字裡的 HTML 標籤<!--[\s\S]*?-->HTML 註解//.*$以兩個斜線開頭的註解/\*[\s\S]*?\*/跨越多行的註解"[^"\\]*(?:\\.[^"\\]*)*"雙引號裡的內容'[^'\\]*(?:\\.[^'\\]*)*'單引號裡的內容\[([^\]]+)\]\(([^)]+)\)Markdown 連結^#{1,6}\s+.+$Markdown 標題行(?:^|\s)#([a-z0-9_]+)主題標籤(?:^|\s)@([a-z0-9_]{2,})用 @ 提到的名字[?&]([^=&]+)=([^&]*)網址問號後面的參數https?://[^\s<>"]+夾在正文裡的網址^https?://([^/:?#]+)從網址裡只取網域名稱\.([a-z0-9]+)$檔名的副檔名(?<=[a-z0-9])(?=[A-Z])駝峰寫法裡詞與詞的接縫_([a-z])底線後面的那個字母-([a-z])連字號後面的那個字母(?:^|,)("(?:[^"]|"")*"|[^,]+)用逗號分開的一個欄位^([^=]+)=(.*)$用等號分開的名字和值^\s*(\S+)第一個詞(\S+)\s*$最後一個詞\d+文字裡成串的數字\b\w+\b一個一個詞\[([^\]]*)\]方括號裡的內容\(([^)]*)\)圓括號裡的內容[\uD800-\uDBFF][\uDC00-\uDFFF]占兩個碼元的表情符號(.)\1{2,}同一個字元出現三次以上,\s*([}\]])閉合括號前多出來的逗號怎麼看這一頁
- 兩端加上 ^ 和 $,整個字串就必須合上;不加,比對落在文中任何位置都行。用來做輸入檢查的式子,一定要加錨。
- 圓括號 ( ) 會把括住的部分擷取下來。只是想分組的話寫成 (?: ),後面各組的編號才不會往後挪。
- 這裡的每個式子都拿它自己的例子跑過。不過「長得像電子郵件」和「真有這個信箱」始終是兩回事。
- 開放式重複層層巢狀(比如 (a+)+)時,遇到某些輸入耗時會爆炸式增長。把別人的式子貼進程式前,先找找有沒有這種形狀。
常見問題
Q. 什麼是正規表示式?
它是一門小語言,用來描述你想在文字裡找的「形狀」。寫 \d{4} 而不是「四位數字」,程式就能找出每一處符合這個形狀的地方。JavaScript、Python、Java 等大多數語言用的寫法幾乎相同。
Q. 電子郵件的檢查式為什麼這麼短?
完全照標準寫的郵件式子長達數千字元,而且照樣說不出這個信箱是否真的存在。擋住手滑打錯,才是正規表示式能做的事;真正的確認只有寄一封驗證信。
Q. 為什麼同一個式子在各語言裡略有不同?
骨架一樣,細節不同。JavaScript 沒有 \A,Python 要單獨打開 re.MULTILINE。這裡列出的式子都是按在 JavaScript 裡原樣能跑的形式寫的。
Q. 說式子可能很慢,是什麼意思?
像 (a+)+ 這樣開放式重複巢在一起時,遇到比對不上的輸入,回溯的路數會爆炸。這時哪怕很短的字串也可能耗上好幾秒,放在伺服器上很危險。
Q. 這裡的式子可信嗎?
每個式子都帶著「必須符合」和「必須不符合」兩組例子,測試會把 133 個全部真跑一遍。頁面上看到的例子就是測試用的例子,所以說明和式子不可能各走各的。