正则表达式测试器

输入正则表达式和测试文本,实时高亮匹配的部分,并显示每个匹配的位置、捕获分组(含命名分组)和替换结果。常用模式一键载入。所有处理都在浏览器内完成。

//
标志: g 全部匹配 · i 忽略大小写 · m 多行 · s 点号匹配换行 · u Unicode · y 固定位置。不带g时只显示第一个匹配。

正则表达式是什么,这个测试器如何运行

正则表达式(regex)是用符号描述文本“形状”的写法,可以用来搜索、校验、提取和替换。像“以1开头、共11位的数字”这样用话说起来很长的条件,用一行就能写完,所以常用于表单校验、日志分析、批量改文本和爬取后的数据清洗。

本工具直接使用浏览器内置的JavaScript(ECMAScript)正则引擎,在这里通过的写法可以原样放进JavaScript或TypeScript的 new RegExp(...) 或 /模式/标志 中。 PHP的PCRE、Python、Java、.NET等各有自己的方言,基础相同但细节不同,见后文“与其他语言的差异”。 所有处理都在你的浏览器里完成:你输入的模式和测试文本不会被发送,也不会被保存。即便如此,测试时也不必粘贴真实的个人信息,用虚构的示例文本就够了。

基本语法速查

写法含义示例
.除换行外的任意一个字符(带s标志时包含换行)a.c → abc、a1c
\d \w \s数字 / 英文字母、数字和下划线 / 空白字符\d\d → 12
[abc] [^abc]集合中的一个字符 / 不在集合中的一个字符[A-Z] → 大写字母
* + ?0次或多次 / 1次或多次 / 0或1次ab+ → ab、abbb
a{2,3}重复2到3次\d{4} → 恰好4位数字
^ $字符串(带m标志时为每一行)的开头 / 结尾^abc$
\b单词边界(单词字符与非单词字符之间)\bcat\b
(…) (?:…)捕获分组 / 非捕获分组(ab)+
a|b或cat|dog
(?=…) (?!…)先行断言(后面有 / 没有…)\d+(?=%)
(?<=…) (?<!…)后行断言(前面有 / 没有…)(?<!\d)\d{5}(?!\d)

处理中文时必须知道:\w 和 \b 只把英文字母、数字和下划线当作“单词字符”,汉字不是单词字符。所以 \w+ 抓不到中文,\bcat\b 甚至能在“cat猫”里匹配成功。 要匹配汉字,请加上u标志,用Unicode属性,例如 \p{Script=Han}+;老式写法 [\u4e00-\u9fff] 只覆盖基本汉字区,不含扩展区等。

标志(flags)

较新的引擎还有 d(返回分组位置)和 v(扩展的Unicode模式),仅在浏览器支持时可用。本工具会把输入的标志原样交给浏览器,不支持或重复的标志会显示为错误信息。不带g时只显示第一个匹配,效果与调用一次 exec() 相同。

常用模式(均已在Node.js中运行验证)

下面的模式都放进了上方的示例按钮,示例文本确实按说明被匹配或排除。

电子邮箱

\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b(标志gi)能匹配 alex@example.com 和 a.b+c@mail.co.uk,并排除没有顶级域名的 bad@x 和 @no.com。 不过邮箱地址的完整规范(RFC 5322)复杂得多,短模式不可能放行所有合法地址、挡住所有错误。把它当作初步筛选,是否真实存在要靠发送验证邮件来确认。

手机号与邮政编码

(?<!\d)1[3-9]\d{9}(?!\d) 匹配以1开头、第二位为3到9的11位数字,前后不能紧挨着其他数字。示例中 13812345678 和 19987654321 通过,12345678901(第二位是2)和12位的 138123456789 被排除。 邮政编码用 (?<!\d)\d{6}(?!\d),找出前后不连着其他数字的6位数字,100000 与 518000 会匹配,5位的电话片段不会。 这些只检查“格式”:号段分配会随时间调整,而且格式正确不代表号码真实存在,需要确认时请以运营商或官方渠道为准。

日期(YYYY-MM-DD)

\b(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])\b 把月份限制在01到12、日期限制在01到31,并分别捕获年、月、日。示例中的 2026-13-01 被排除,但 2026-02-31 会通过:正则只看格式,不知道日历。日期是否真实存在,请在正则之后用日期库验证。

汉字、网址、IPv4、颜色代码

贪婪与非贪婪匹配

*、+、a{2,3} 默认是贪婪的,尽可能多地匹配;在后面加 ? 就变成非贪婪(惰性),尽可能少地匹配。 对 <b>第一</b> 和 <b>第二</b>,贪婪的 <b>.*<\/b> 会把从第一个开始标签到最后一个结束标签整段当作一个匹配,而惰性的 <b>.*?<\/b> 则分成两个匹配。最后两个示例按钮可以让你直接看到匹配数是1个还是2个。 更稳妥的做法是用“排除结束字符”的否定字符类,例如 [^<]*,运行行为也更容易预测。

ReDoS:正则如何让页面卡死

JavaScript的引擎采用回溯方式:一条路走不通就退回去试另一条。如果模式里有“重复套重复”,输入变长时尝试的路径数会急剧膨胀,这就是ReDoS(正则表达式拒绝服务)。 典型例子是 ^(a+)+$。对一串a后面再跟一个b的文本,它要把a在内外两层加号之间的所有分配方式都试一遍才会失败。我在Node.js中实测:24个a约0.1秒,26个a约0.4秒,每多一个a耗时大约翻倍(具体数值与机器有关),到40个就基本跑不完了。 意思相同的 ^a+$ 则瞬间结束。如果在本页试验时标签页卡住,请等待浏览器提示或直接关闭标签页。

计算超过100毫秒时,状态栏会给出警告。运行中的计算无法被打断,所以可疑的模式请先用很短的文本测试。

分组、命名分组与替换

括号包起来的部分是捕获分组,会按编号显示在匹配列表中。像 (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) 这样给分组命名,就能按名字取值,模式再长也好维护。 在替换框中可以使用 $1(第1组)、$&(整个匹配)和 $<名称>(命名分组)。验算示例:载入日期模式,测试 2026-10-13,替换内容写 $3/$2/$1,结果是 13/10/2026;命名分组的示例按钮用 $<day>/$<month>/$<year> 得到同样的结果。 没有参与匹配的可选分组会显示为“(无)”。

容易踩的坑

与其他语言的差异

什么时候不该用正则

HTML、XML、JSON这类嵌套结构无法只靠正则可靠地解析,请使用专门的解析器(JSON可以用JSON格式化与校验工具)。邮箱是否存在、日期是否在日历上、手机号是否在用,这些“含义”层面的校验也不是正则的任务。 正则适合做格式过滤,含义校验请交给另外的逻辑。

常见问题

在哪里查看捕获分组?

把想取出的部分用括号括起来,匹配列表的每一项下面就会按分组编号显示对应的值;命名分组还会同时显示名称。

模式写错了会怎样?

出现语法错误时,状态栏会显示浏览器返回的错误信息。请检查括号是否成对、特殊字符是否转义、量词前是否有可重复的内容,以及标志是否正确。

去掉g标志为什么只显示一个匹配?

没有g时,JavaScript的正则在第一个匹配处就停止。要找出全部匹配或替换全部内容,请加上g。

我输入的文本会被发送出去吗?

不会。模式和测试文本由本页上浏览器自带的正则引擎处理,工具不会发送也不会保存它们。

能用邮箱正则完美判断地址是否有效吗?

不能。正则只能检查格式,无法判断地址是否真实存在。发送验证邮件才是最可靠的方式,正则只适合作为过滤明显笔误的初步筛选。

相关工具