正規表達式測試器
还没有匹配结果
输入正则与文本后,这里会展示每个匹配、捕获组和命名分组。
统计
命名分组汇总
当前没有命名分组。
免費線上正規表達式測試器(Regex Tester),支援JS即時匹配測試、擷取群組/命名群組檢視、取代預覽、正規語法解釋,內建Web Worker防ReDoS逾時保護,附常用正規範本庫,適合開發者快速除錯和驗證正規。
还没有匹配结果
输入正则与文本后,这里会展示每个匹配、捕获组和命名分组。
统计
命名分组汇总
当前没有命名分组。
免費線上正規表達式測試器(Regex Tester),支援JS即時匹配測試、擷取群組/命名群組檢視、取代預覽、正規語法解釋,內建Web Worker防ReDoS逾時保護,附常用正規範本庫,適合開發者快速除錯和驗證正規。
ReDoS(Regular Expression Denial of Service,正規表達式拒絕服務攻擊)是指某些惡意構造的正規表達式(如 `(a+)+$` 匹配長字串)會觸發災難性回溯(catastrophic backtracking),導致CPU佔用100%、瀏覽器卡死或伺服器崩潰。本工具使用 Web Worker 沙箱執行正規匹配,設定 500ms 逾時自動中斷,即使輸入會觸發回溯的惡意正規也不會卡死你的瀏覽器,這是本工具的核心安全特性。
g(global)全域匹配,尋找所有匹配項而非第一個;i(ignoreCase)忽略大小寫;m(multiline)多行模式,使 ^ 和 $ 匹配每行開頭/結尾;s(dotAll)讓點號 . 匹配包括換行符號在內的所有字元;u(unicode)Unicode模式,正確處理 emoji 和多位元組字元;y(sticky)黏著匹配,從 lastIndex 位置開始精確匹配。本工具提供了6個旗標的視覺化切換按鈕,點擊即可即時開關。
擷取群組用圓括號 `(pattern)` 包裹,匹配後可透過 $1、$2 等參考擷取子字串。命名群組用 `(?<name>pattern)` 語法,匹配後可透過 `$<name>` 參考,程式可讀性更高。例如用 `(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})` 匹配日期後,可以在取代字串中用 `$<year>年$<month>月$<day>日` 重新格式化。本工具會自動列出每個匹配的擷取群組和命名群組結果。
本工具基於 JavaScript 原生 RegExp 引擎,與 JS/TypeScript、Python re 模組、Java java.util.regex、PHP preg_*、Go regexp 等主流引擎語法大體相容(都基於 PCRE/Perl 流派),主要差異在一些進階特性(如 Python 的 `(?P<name>)` 命名群組寫法、.NET 的可變長度lookbehind)。日常開發中 99% 的正規(電子郵件、手機、URL、日期等驗證/擷取)在各引擎間通用,可以直接在本工具測試後複製到程式中使用。
點擊頂部工具列的「分享」按鈕,工具會自動將目前正規表達式、旗標、測試文字編碼到URL參數中,並複製連結到剪貼簿。同事打開連結即可看到完全一致的測試狀態(pattern+flags+testText),非常適合團隊協作和遠端除錯。
在取代字串中:$1、$2...表示第N個擷取群組;$& 表示整個匹配的文字;$` 表示匹配文字之前的部分;$' 表示匹配文字之後的部分;$$ 表示字面值 $;$<name> 表示命名群組。例如將 `(\d{4})-(\d{2})-(\d{2})` 取代為 `$2/$3/$1` 可將 2026-03-12 轉為 03/12/2026。本工具的取代區提供了這些特殊符號的快捷插入按鈕。
正規表達式(Regular Expression,簡稱Regex/RegExp)是一種用單個字串描述、匹配一系列符合某個句法規則的字串的文字模式語言。它的歷史可以追溯到1950年代神經學家Warren McCulloch和數學家Walter Pitts提出的神經元數學模型,後來數學家Stephen Kleene在1956年在此基礎上提出了「正規集合」的代數描述。Unix之父Ken Thompson在1960年代末將正規表達式首次實作在QED編輯器中,此後正規表達式成為Unix工具鏈(grep、sed、awk、vi)的核心功能。
現代程式語言中,正規表達式幾乎是標配能力——JavaScript的RegExp、Python的re模組、Java的java.util.regex、.NET的Regex類別、Go的regexp套件都提供了正規支援。正規表達式廣泛應用於表單驗證(電子郵件/手機/身分證)、文字搜尋與取代(編輯器尋找取代)、日誌分析(擷取ERROR日誌)、網路爬蟲(HTML內容擷取)、資料清洗(ETL)、路由匹配、輸入過濾和安全防護(WAF規則)等場景。
正規表達式的核心概念包括:字元類(\d數字、\w單字元、\s空白)、量詞(*零或多、+一或多、?零或一、{n,m}指定次數)、錨點(^開頭、$結尾、\b單字邊界)、群組((...)擷取群組、(?:...)非擷取群組、(?<name>...)命名群組)、分支(|)、字元集([a-z])、環視((?=...)正向預查、(?!)負向預查)等。掌握正規可以極大提升文字處理效率,但也需要注意防範ReDoS等效能陷阱。
| 中繼字元 | 含義 | 範例說明 |
|---|---|---|
. | 任意單個字元(不含換行,s旗標下含換行) | a.c 匹配 abc、aXc,不匹配 a\nc |
\d | 數字字元,等價於 [0-9] | \d{3} 匹配 123、456 |
\w | 單字字元,等價於 [A-Za-z0-9_] | \w+ 匹配 hello_123 |
\s | 空白字元(空格/定位字元/換行等) | a\sb 匹配 a b(中間空格) |
^ | 字串開頭(m旗標下為行首) | ^Hello 匹配行首的Hello |
$ | 字串結尾(m旗標下為行尾) | end$ 匹配行尾的end |
\b | 單字邊界 | \bcat\b 匹配獨立單字cat,不匹配category |
* | 前一元素重複 0 次或多次(貪婪) | ab*c 匹配 ac、abc、abbc |
+ | 前一元素重複 1 次或多次 | ab+c 匹配 abc、abbc,不匹配ac |
? | 前一元素 0 次或 1 次(或用於非貪婪/環視) | colou?r 匹配 color和colour |
| | 分支/或,匹配左邊或右邊 | cat|dog 匹配cat或dog |
[...] | 字元集合,匹配其中任一字元 | [aeiou] 匹配任一元音字母 |
| 用途 | 正規表達式 | 推薦旗標 |
|---|---|---|
| 電子郵件地址 | [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} | g |
| 中國大陸手機號碼 | 1[3-9]\d{9} | g |
| URL連結 | https?:\/\/[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b[-a-zA-Z0-9()@:%_+.~#?&/=]* | gi |
| IPv4位址 | \b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b | g |
| 日期 YYYY-MM-DD | \d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01]) | g |
| 身分證字號(18位) | [1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}[\dXx] | g |
| UUID | [0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12} | gi |
// 驗證電子郵件格式
const emailRe = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
console.log(emailRe.test('user@example.com')); // true
// 擷取命名群組(日期解析)
const dateRe = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/g;
const text = '會議時間:2026-03-12,截止:2026-04-01';
const matches = [...text.matchAll(dateRe)];
for (const m of matches) {
console.log(m.groups.year, m.groups.month, m.groups.day);
}
// 取代:日期格式轉換 YYYY-MM-DD → MM/DD/YYYY
const reformatted = text.replace(dateRe, '$<month>/$<day>/$<year>');
console.log(reformatted);
// 會議時間:03/12/2026,截止:04/01/2026import re
# 尋找所有匹配項
text = '聯絡:alice@example.com,bob@test.org'
emails = re.findall(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}', text)
print(emails) # ['alice@example.com', 'bob@test.org']
# 命名群組擷取(Python 用 ?P<name> 語法)
date_pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
m = re.search(date_pattern, '發布於 2026-03-12')
if m:
print(m.group('year'), m.group('month'), m.group('day'))
# 取代:手機號碼中間4位遮罩
phone_re = r'(1[3-9]\d)\d{4}(\d{4})'
result = re.sub(phone_re, r'\1****\2', '手機號碼:13812345678')
print(result) # 手機號碼:138****5678import java.util.regex.*;
class RegexDemo {
public static void main(String[] args) {
String text = "Error [2026-03-12 18:05:09] Connection failed";
// 編譯正規(生產環境應快取 Pattern 實例)
Pattern p = Pattern.compile(
"(?<level>INFO|WARN|ERROR)\\s+\\[(?<time>[^\\]]+)\\]\\s+(?<message>.+)"
);
Matcher m = p.matcher(text);
if (m.find()) {
System.out.println("級別: " + m.group("level"));
System.out.println("時間: " + m.group("time"));
System.out.println("訊息: " + m.group("message"));
}
// 取代所有數字
String cleaned = "abc123def456".replaceAll("\\d+", "*");
System.out.println(cleaned); // abc*def*
}
}