正则表达式是什么,这个测试器如何运行
正则表达式(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)
- g(global):找出全部匹配,而不是在第一个就停下。替换时没有g则只替换第一处。
- i(ignore case):忽略英文字母的大小写。
- m(multiline):
^和$匹配每一行的开头和结尾,而不是整段文本的。按行校验时必不可少。 - s(dotAll):让
.也能匹配换行,适合跨多行的标签。 - u(unicode):按码点而不是16位单元处理文本,并可使用
\p{Script=Han}+这样的属性转义。没有u时,一个emoji会被算作两个字符:/^.$/无法匹配“😀”,而/^.$/u可以。 - y(sticky):只在
lastIndex指定的位置尝试匹配。
较新的引擎还有 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、颜色代码
- 汉字:
\p{Script=Han}+(标志gu)。在“你好 world 正则表达式 123”中会取出“你好”和“正则表达式”两段。 - 网址:
https?:\/\/[^\s<>"']+取到空白、尖括号或引号之前。句末的标点或括号可能被一起带上,需要后处理。 - IPv4:每段数字由能覆盖0到255的几种写法组合而成,
192.168.0.1会匹配,256.1.1.1和1.2.3被排除。 - 十六进制颜色:
#(?:[0-9a-fA-F]{3}){1,2}\b只允许3位或6位,#fff和#C9A961匹配,#12345不匹配。
贪婪与非贪婪匹配
*、+、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+$ 则瞬间结束。如果在本页试验时标签页卡住,请等待浏览器提示或直接关闭标签页。
- 避免“重复的分组里再含重复”,如
(a+)+、(.*)*,以及分支相互重叠的重复选择,如(a|a)+、(a|aa)+。 - 对用户输入使用正则之前,先限制输入长度。
- 尽量用具体的字符类代替
.*。 - 不要在服务器上直接执行不受信任的用户提供的模式。
计算超过100毫秒时,状态栏会给出警告。运行中的计算无法被打断,所以可疑的模式请先用很短的文本测试。
分组、命名分组与替换
括号包起来的部分是捕获分组,会按编号显示在匹配列表中。像 (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) 这样给分组命名,就能按名字取值,模式再长也好维护。 在替换框中可以使用 $1(第1组)、$&(整个匹配)和 $<名称>(命名分组)。验算示例:载入日期模式,测试 2026-10-13,替换内容写 $3/$2/$1,结果是 13/10/2026;命名分组的示例按钮用 $<day>/$<month>/$<year> 得到同样的结果。 没有参与匹配的可选分组会显示为“(无)”。
容易踩的坑
- 对带g的正则反复调用test():带g的正则会记住
lastIndex,对同一个对象连续调用test()结果会交替变化(对“aa”用/a/g依次得到true、true、false)。请每次新建,或把lastIndex重置为0。 - 空匹配:
'abc'.match(/x*/g)会在每个位置返回一个空字符串,共4个。本工具会在列表中列出空匹配,但不做高亮。 - 字符串里的转义:在JavaScript字符串中,反斜杠要写两次(
"\\d")。在本工具的输入框中直接写\d即可。 - 全角与半角:全角数字“123”不会被
\d匹配,需要时请单独写范围,如[0-9]。
与其他语言的差异
- JavaScript没有PCRE的行内标志
(?i)、占有量词a++和原子分组。 - Python的命名分组写成
(?P<名称>…),JavaScript则是(?<名称>…)。 - 有些语言用
\A、\z表示文本的绝对开头和结尾;JavaScript在没有m标志时用^和$。 - 后行断言在当前的主流浏览器中可用,如果要兼容旧环境请先确认。
什么时候不该用正则
HTML、XML、JSON这类嵌套结构无法只靠正则可靠地解析,请使用专门的解析器(JSON可以用JSON格式化与校验工具)。邮箱是否存在、日期是否在日历上、手机号是否在用,这些“含义”层面的校验也不是正则的任务。 正则适合做格式过滤,含义校验请交给另外的逻辑。
常见问题
在哪里查看捕获分组?
把想取出的部分用括号括起来,匹配列表的每一项下面就会按分组编号显示对应的值;命名分组还会同时显示名称。
模式写错了会怎样?
出现语法错误时,状态栏会显示浏览器返回的错误信息。请检查括号是否成对、特殊字符是否转义、量词前是否有可重复的内容,以及标志是否正确。
去掉g标志为什么只显示一个匹配?
没有g时,JavaScript的正则在第一个匹配处就停止。要找出全部匹配或替换全部内容,请加上g。
我输入的文本会被发送出去吗?
不会。模式和测试文本由本页上浏览器自带的正则引擎处理,工具不会发送也不会保存它们。
能用邮箱正则完美判断地址是否有效吗?
不能。正则只能检查格式,无法判断地址是否真实存在。发送验证邮件才是最可靠的方式,正则只适合作为过滤明显笔误的初步筛选。
相关工具
- 文本比较(Diff)工具 - 查看替换前后的差异
- JSON格式化与校验工具 - JSON请用解析器而不是正则
- 文本大小写/命名格式转换器 - 大小写与命名风格转换
- URL编码器/解码器 - 转换网址中的特殊字符