正则表达式测试器

使用实时突出显示、捕获组和解释来测试正则表达式。

免费在线正则表达式测试器

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

常见问题

regex 代表什么?
Regex 是 regular expression(正则表达式)的缩写。该术语来自计算机科学中的形式语言理论,正则表达式用于描述正则语言。实践中,现代正则引擎支持反向引用、环视等超出形式定义的功能。
如何用正则匹配邮箱地址?
常用模式是 [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}。这可匹配大多数标准邮箱格式。然而,完整的邮箱规范(RFC 5322)允许引号字符串、注释等边界情况,简单正则无法全部处理。生产环境中,可用正则宽松验证格式,再通过发送验证邮件确认投递。
正则中 * 与 + 有什么区别?
* 匹配前面元素零次或多次。+ 匹配一次或多次。例如,a* 匹配「」(空字符串)、「a」、「aa」、「aaa」等。a+ 匹配「a」、「aa」、「aaa」,但不匹配空字符串。当你需要至少匹配一次时,使用 +。
什么是正则标志?
标志会修改模式的应用方式。常用标志:g(全局)查找所有匹配而不在第一个处停止。i(忽略大小写)使 [a-z] 也能匹配大写字母。m(多行)使 ^ 和 $ 匹配每行的开头和结尾,而不只是整个字符串。s(dotAll)使 . 匹配换行符。u(unicode)启用完整 Unicode 匹配。
什么是非捕获组?
非捕获组 (?:...) 为交替或量词对元素进行分组,但不存储匹配的文本。普通组 () 将匹配捕获到编号引用($1、$2)。当你需要分组但不需要捕获值时,使用非捕获组——它们稍高效一些。
为什么我的正则很慢(灾难性回溯)?
灾难性回溯发生在模式具有嵌套量词或重叠的交替,从而产生指数级匹配路径时。例如:在长且不匹配的字符串上使用 (a+)+。引擎会在失败前尝试拆分输入的每一种方式。可通过占有量词 (a++)、原子组,或重构模式以消除歧义来修复。
如何在正则中转义特殊字符?
在前面加反斜杠:\. 匹配字面点号,\[ 匹配字面方括号,\\ 匹配字面反斜杠。需要转义的特殊字符:. * + ? ^ $ { } [ ] ( ) | \。在字符类 [...] 内部,大多数字符是字面的——只有 ]、\、^ 和 - 需要转义。
贪婪匹配与惰性匹配有什么区别?
贪婪量词(*、+、{n,})尽可能多地匹配文本。惰性量词(*?、+?、{n,}?)尽可能少地匹配。例如,给定字符串「<b>bold</b>」,模式 <.*>(贪婪)匹配整个字符串,而 <.*?>(惰性)只匹配「<b>」。当你想要最短匹配时,使用惰性匹配。