免費線上正規表示式測試器
正規表示式支援跨每種語言的驗證、解析和搜尋。 Dokall 的正規表示式遊樂場可讓您鍵入模式、切換標誌並立即查看反白顯示的符合項目 - 包含擷取羣組和基本標記説明。
使用電子郵件、URL、電話號碼、日期等的預設模式,或建立自己的模式。一切都在您的瀏覽器中運行 - 沒有資料發送到伺服器。
什麼是正則表達式?
正則表達式(regex)是一種描述字符串集合的模式。它用於搜索、匹配、提取和替換文本。幾乎每種編程語言、文本編輯器和命令行工具都以某種形式支持正則。
簡單的正則如 [0-9]{3}-[0-9]{4} 可匹配 555-1234 這類電話號碼片段。更復雜的模式可驗證郵箱格式、解析日誌檔案、從 HTML 中提取 URL,或在數千個檔案中查找並替換。學習正則很快就能帶來回報,因為它是可跨語言和工具遷移的通用技能。
正則語法速查
字面字符匹配自身:abc 匹配字符串「abc」。點號 . 匹配除換行外的任意單個字符。反斜槓 \ 轉義特殊字符:\. 匹配字面點號。
字符類定義集合:[aeiou] 匹配任意元音,[0-9] 匹配任意數字,[^0-9] 匹配任意非數字。速記類可節省輸入:\d 表示數字,\w 表示單詞字符(字母、數字、下劃線),\s 表示空白。
錨點匹配位置而非字符:^ 匹配行首,$ 匹配行尾。\b 匹配單詞邊界——適用於匹配完整單詞而避免部分匹配。
交替使用豎線:cat|dog 匹配「cat」或「dog」。用括號分組交替:(cat|dog) food 匹配「cat food」或「dog food」。
量詞:匹配多少次
量詞指定重複次數。* 表示零次或多次,+ 表示一次或多次,? 表示零次或一次。{n} 表示恰好 n 次,{n,} 表示 n 次或更多,{n,m} 表示 n 到 m 次之間。
預設情況下,量詞是貪婪的——儘可能多地匹配。模式 ".*" 應用於 "hello" "world" 會匹配包含兩個引號在內的整個字符串。加上 ? 使其變為惰性:".*?" 只匹配 "hello"。
貪婪與惰性的區別是最常見的正則 bug 來源之一。當模式匹配超出預期時,嘗試切換為惰性量詞,或使用否定字符類如 [^"]* 代替 .*。
捕獲組與反向引用
括號創建捕獲組,用於提取匹配的部分。模式 (\d{4})-(\d{2})-(\d{2}) 應用於「2024-01-15」時,組 1 捕獲「2024」,組 2 捕獲「01」,組 3 捕獲「15」。
在替換字符串中,你可以引用捕獲組:將 (\w+)@(\w+) 替換為 $1 at $2,會把「user@host」變成「user at host」。模式內部的反向引用使用 \1、\2 等:(\w+)\s+\1 匹配「the the」這類重複單詞。
非捕獲組 (?:...) 進行分組但不捕獲。當你需要為交替或量詞分組,但不需要提取匹配文本時使用它們。它們稍快一些,因為引擎無需存儲匹配內容。
前瞻與後顧
前瞻與後顧(統稱環視)斷言當前位置之前或之後存在某模式,但不會將其包含在匹配中。
肯定前瞻 (?=...) 在前方模式存在時匹配:\d+(?= dollars) 匹配「100 dollars」中的「100」,但不匹配「100 euros」。否定前瞻 (?!...) 在前方模式不存在時匹配:\d+(?! dollars) 匹配「100 euros」中的「100」。
肯定後顧 (?<=...) 在後方模式存在時匹配:(?<=\$)\d+ 匹配「$50」中的「50」。否定後顧 (?<!...) 用於排除:(?<!\$)\d+ 匹配前面沒有美元符號的「50」。
環視是零寬的——它們檢查條件而不消耗字符。這使它們在複雜匹配規則中很強大,同時不改變被捕獲或替換的內容。
常用正則模式
郵箱(基礎):[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} —— 匹配大多數常見郵箱格式。生產環境驗證請使用語言自帶的郵箱庫,而非正則。
URL:https?://[^\s]+ —— 匹配 HTTP 和 HTTPS URL。嚴格的 URL 驗證會使模式複雜得多。
IPv4 地址:\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b —— 匹配四個以點分隔的數字組。不會驗證每個八位組是否在 0–255 範圍內。
ISO 日期:\d{4}-\d{2}-\d{2} —— 匹配 YYYY-MM-DD 格式。不會驗證月/日範圍。
強密碼檢查:^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d]).{8,}$ —— 要求至少一個小寫、一個大寫、一個數字、一個特殊字符,且最少 8 個字符。使用多個前瞻。
正則性能:避免災難性回溯
正則引擎會嘗試每一種可能的匹配方式。某些模式會導致指數級回溯——引擎在失敗前探索大量路徑。這可能使你的應用卡死。
經典例子是 (a+)+ 應用於一串 a 後跟一個不匹配字符。引擎會嘗試內外組之間拆分 a 的每一種方式,然後才斷定無匹配。對於 25 個 a,這可能需要數十億步。
避免災難性回溯的方法:在引擎支持時使用原子組 (?>...) 或佔有量詞 a++,優先使用具體字符類而非 .*,避免 (a+)+ 這類嵌套量詞,並用長且不匹配的輸入測試模式。如果模式耗時超過幾毫秒,很可能存在風險。