免费在线正则表达式测试器
正则表达式支持跨每种语言的验证、解析和搜索。 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+)+ 这类嵌套量词,并用长且不匹配的输入测试模式。如果模式耗时超过几毫秒,很可能存在风险。