正则表达式在线测试怎么用
- 输入正则表达式,不要带两边的斜杠:写
\d+,不写/\d+/。 - 填写标志,例如
g找出全部匹配,gi同时忽略大小写;匹配汉字的\p{…}写法需要加u。 - 粘贴测试文本。每个匹配都会在文本里高亮,下面的表格列出每个匹配的位置和各个捕获组取到的内容。
- 试试替换:选择匹配并替换,在替换框里用
$1或$<name>引用分组,替换结果显示在最上面,可以一键复制。 - 复制到代码里:结果里同时给出正则字面量和
new RegExp(…)写法,后者的反斜杠已经按字符串规则加倍。
正则有语法错误时,会用中文说明问题和改法,后面附上浏览器的原始报错。
这是哪一种正则
正则表达式有很多“方言”。这个工具直接用你浏览器里的 JavaScript 引擎运行——Chrome 和 Edge 是 V8,Firefox 是 SpiderMonkey,Safari 是 JavaScriptCore——它们都遵循 ECMAScript 标准,所以在这里能用的正则,放进 JavaScript、TypeScript、Node.js、小程序或 uni-app 里结果一样。大部分语法和 PCRE(PHP)、Python 的 re、Java、Go 相同,但有几处差别:
| 特性 | JavaScript(本工具) | PCRE、Python、Java |
|---|---|---|
后行断言 (?<=…) (?<!…) | 支持,长度不限 | 支持;Python 和 Java 要求长度固定或有上限 |
| 命名分组 | (?<name>…)、\k<name>,替换时用 $<name> | Python 写作 (?P<name>…) 和 \g<name> |
占有量词 a++、原子分组 (?>…) | 不支持 | PCRE、Java 支持;Python 3.11 起支持 |
\d、\w、\b | 只认 ASCII:\w 不匹配汉字,\d 只匹配 0–9 | Python 3 默认按 Unicode:\w 能匹配汉字 |
Unicode 属性 \p{Script=Han} | 加 u 或 v 标志后支持 | PCRE 写作 \p{Han};Java 支持;Python 的 re 不支持 |
| Go 的 RE2 | — | Go 不支持反向引用和任何断言 |
内联标志 (?i) | 不能写在整个正则开头;最新的浏览器支持局部的 (?i:…) | 支持 |
不加 u 或 v 标志时,JavaScript 会把不认识的转义当成普通字母:\A 匹配“A”,\p{L} 匹配“p{L}”。工具会对这两种情况给出提醒。
用正则匹配中文:[\u4e00-\u9fa5] 和 \p{Script=Han} 的区别
网上流传最广的“匹配中文”正则是 [\u4e00-\u9fa5]。它能用,但只覆盖 1993 年 Unicode 1.1 收录的基本汉字区,后来新增的字、扩展区的生僻字和“〇”都不在里面。下面是三种写法在同一句话里实际找到的内容(由本工具的匹配代码计算):
测试文本:二〇二六年十月,新元素“鿏”和生僻字“𠮷”都要能搜到。
| 正则 | 标志 | 找到的内容 | 说明 |
|---|---|---|---|
[一-龥]+ | g | 二、二六年十月、新元素、和生僻字、都要能搜到 | 最常见的写法,只覆盖 1993 年 Unicode 1.1 收录的 20,902 个基本汉字(U+4E00–U+9FA5) |
[一-鿿]+ | g | 二、二六年十月、新元素、鿏、和生僻字、都要能搜到 | 覆盖整个“中日韩统一表意文字”基本区(20,992 个码位),包括后来补进的“鿏”等字 |
\p{Script=Han}+ | gu | 二〇二六年十月、新元素、鿏、和生僻字、𠮷、都要能搜到 | 所有汉字:基本区、扩展 A–扩展 I、兼容汉字、部首,以及“〇”“々”;必须加 u(或 v)标志 |
可以看到:
- “〇”(U+3007)不在
[\u4e00-\u9fa5]里,所以“二〇二六年”被拆断了。写中文年份、门牌号时这个字很常见。 - “鿏”(U+9FCF)是后来补进基本区末尾的字(化学元素名),U+9FA5 之后还有几十个这样的字。
- “𠮷”(U+20BB7)属于扩展 B 区,在 JavaScript 字符串里占两个 UTF-16 码元。不加 u 标志时,
.和[\u4e00-\u9fff]都只能看到它的半个;只有\p{Script=Han}加 u 标志才能把它当成一个字。人名、地名里的生僻字大多在扩展区。 - 中文标点“,”“。”““”不是汉字,三种写法都不匹配它们。要匹配全角标点,可以用
[\u3000-\u303f\uff00-\uffef](CJK 标点和全角字符两个区),不过“〇”也落在前一个区里。 \p{Script=Han}匹配的是“汉字”这个文字系统,所以日文里的汉字、韩文里的汉字同样会被匹配,日文假名和韩文字母则不会。
结论:新代码请用 /\p{Script=Han}/u;如果必须兼容很老的环境,至少用 [\u4e00-\u9fff]。另外注意 \w 在 JavaScript 里不包括汉字,“用户名只能是中文、字母、数字”应写成 ^[\p{Script=Han}A-Za-z0-9_]+$ 并加 u 标志。
正则速查表
字符和字符集
| 写法 | 匹配 |
|---|---|
. | 除换行外的任意字符(加 s 后包括换行) |
\d \D | 数字 0–9 / 非数字 |
\w \W | 字母、数字、下划线(只限 ASCII,不含汉字)/ 其他字符 |
\s \S | 空白(空格、制表符、换行,也包括全角空格)/ 非空白 |
[abc] | a、b、c 中的一个 |
[^abc] | 除 a、b、c 以外的任意字符 |
[a-z0-9] | 范围:小写字母或数字 |
\p{Script=Han} | 一个汉字(需要 u 或 v 标志) |
\. \* \\ | 点号、星号、反斜杠本身:这些字符要加反斜杠转义 . * + ? ^ $ ( ) [ ] { } | \ / |
位置
| 写法 | 匹配 |
|---|---|
^ | 文本开头(加 m 后是每行开头) |
$ | 文本结尾(加 m 后是每行结尾) |
\b | 单词边界:\w 和 \W 之间,汉字与英文字母之间也算 |
\B | 非单词边界 |
量词
| 写法 | 匹配 |
|---|---|
* | 0 次或多次 |
+ | 1 次或多次 |
? | 0 次或 1 次(可有可无) |
{3} | 正好 3 次 |
{2,5} | 2 到 5 次 |
{2,} | 至少 2 次 |
*? +? ?? | 非贪婪(懒惰):尽量少匹配 |
分组和断言
| 写法 | 匹配 |
|---|---|
(abc) | 捕获组,按左括号的顺序从 1 开始编号 |
(?<name>abc) | 命名捕获组 |
(?:abc) | 非捕获分组 |
\1 \k<name> | 与第 1 组 / 命名分组匹配到的相同文本 |
a|b | a 或 b |
(?=abc) (?!abc) | 后面是 / 不是 abc(先行断言) |
(?<=abc) (?<!abc) | 前面是 / 不是 abc(后行断言) |
替换
| 写法 | 匹配 |
|---|---|
$1 $<name> | 第 1 组 / 命名分组的内容 |
$& | 整个匹配 |
$` $' | 匹配前面 / 后面的文本 |
$$ | 美元符号本身 |
常用正则(可直接复制)
复制到输入框里再按需调整。最后一列是每个正则在示例文本中找到的内容,由本工具的代码算出。
| 用途 | 正则 | 标志 | 示例结果 | 说明 |
|---|---|---|---|---|
| 中国大陆手机号 | (?<!\d)1[3-9]\d{9}(?!\d) | g | 客服 13800138000,座机 010-62345678,错号 12345678901。 → 13800138000 | 11 位、以 13–19 开头;前后断言保证不是更长数字的一部分。号段是否真实存在需另行校验。 |
| 18 位身份证号 | [1-9]\d{5}(?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}[\dXx] | g | 身份证号 11010519491231002X 已登记。 → 11010519491231002X | 只检查格式和出生日期的大致范围,不验证最后一位校验码(GB 11643 的加权算法),也不检查 2 月 30 日这类日期。 |
| 邮政编码 | (?<!\d)[1-9]\d{5}(?!\d) | g | 北京市海淀区 100080,上海 200120。 → 100080、200120 | 6 位数字;任何 6 位数都能通过,最好结合上下文使用。 |
| 中文日期 | \d{4}年\d{1,2}月\d{1,2}日 | g | 合同于2026年10月16日签订,2027年1月1日生效。 → 2026年10月16日、2027年1月1日 | 月、日可以是一位或两位数字。 |
| 人民币金额 | [¥¥]\s?\d+(?:\.\d{1,2})? | g | 单价 ¥168.00,运费¥12,合计 ¥ 180。 → ¥168.00、¥12、¥ 180 | 同时接受半角 ¥ 和全角 ¥,以及符号后的一个空格。 |
| 电子邮箱(实用版) | [\w.+-]+@[\w-]+(?:\.[\w-]+)+ | g | 发邮件到 zhang.wei@example.com.cn 或 kefu@shop.cn。 → zhang.wei@example.com.cn、kefu@shop.cn | 能找出常见邮箱,但不是完整的 RFC 5322 校验;邮箱是否有效,只有发一封信才知道。 |
| IPv4 地址 | \b(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\b | g | 网关 192.168.1.1,非法地址 300.1.1.1。 → 192.168.1.1 | 四段数字都必须在 0–255 之间,不能有前导零。 |
| 叠字 | (\p{Script=Han})\1 | gu | 他说得清清楚楚,天天如此。 → 清清、楚楚、天天 | \1 重复第 1 组匹配到的字。 |
计算示例
输入框里的示例正则 (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) 用来找“年-月-日”格式的日期:\d{4} 正好是四位数字,年、月、日各放在一个命名分组里。加 g 标志后,它在示例文本里找到 3 个日期:2026-10-16(位置 10)、2026-11-15(位置 30)、2026-09-30(位置 48)。位置从 0 开始数,每个汉字和中文标点各算 1,所以位置 10 表示匹配前面有 10 个字符。
切换到匹配并替换,替换框里的 $<year>年$<month>月$<day>日 把日期改写成中文格式,第一行变成:“发票 1042 于 2026年10月16日 开具,付款期限为 2026年11月15日。”。如果去掉 g 标志,只有第一个日期会被替换。
灾难性回溯
匹配失败时,引擎会回头尝试其他可能的匹配方式。通常可能性很少,但“重复里套重复”——(a+)+、(\w*)*、(a|aa)+——可以用指数级的方式拆分同一段文本。用 (a+)+$ 去匹配 30 个 a 加一个“!”,引擎要试大约 230 种、超过十亿种拆法才肯放弃,每多一个 a,时间就翻一倍。
JavaScript 的正则一旦开始运行就无法中断,所以很多在线测试工具遇到这种正则会让整个标签页卡死。本工具把匹配放在独立的后台线程(Web Worker)里运行:超过一秒就强制停止,说明原因,并尽量指出正则里嵌套重复的位置。解决办法是让每段文本只有一种匹配方式——用 a+$ 代替 (a+)+$,或者用排除分隔符的字符集,例如用 [^,]* 代替 .*。同样的正则放在服务器上,可能被人利用来拖垮服务(ReDoS),值得认真修改。
小技巧与限制
- 位置按 UTF-16 码元计算,和 JavaScript 字符串下标一致:常用汉字算 1 个,扩展区生僻字和大部分 emoji 算 2 个。加 u 标志后,
.才会把它们当成一个字符。 - 没有 g 标志时只找第一个匹配,也只替换第一个。y(粘连)标志只从当前位置开始匹配,每个匹配必须紧接着上一个。
- 校验整个输入(例如表单里的手机号)时,请用
^…$把正则包起来;不加锚点的话,较长文本中的一部分也会被判定为“通过”。 - 最多统计 10,000 个匹配,表格显示前 1,000 个,高亮显示文本的前 100,000 个字符。
- 处理接口返回的数据时,可以先用 JSON 格式化把内容排好;要统计文本字数,用字数统计;URL 里的 %E4%BD%A0 这类编码可以用 URL 解码还原成中文。
隐私
匹配在你的浏览器里完成,正则和文本都不会上传或记录。页面会在本机记住你上次的输入,方便下次继续;复制链接会把输入放在链接的 # 后面,这部分浏览器不会发送给服务器。
常见问题
这个正则测试工具用的是哪种正则语法?
JavaScript 的正则,也就是 ECMAScript 标准规定、所有浏览器内置的那一种。测试结果和 JavaScript、TypeScript、Node.js、微信小程序里完全一致。PHP、Python、Java 的大部分语法相同,差别见上面的表格。
正则表达式怎么匹配中文?
推荐 \p{Script=Han} 并加 u 标志,例如 /^\p{Script=Han}+$/u 匹配“全是汉字”。常见的 [\u4e00-\u9fa5] 只覆盖基本汉字,“〇”、后来新增的字和扩展区的生僻字(人名里常见)都会漏掉。
为什么在 Python 或 PHP 里能用,这里却报错?
多半用了 JavaScript 没有的语法:(?P<name>…)、a++ 这样的占有量词、原子分组、写在开头的 (?i),或者 \A、\Z。报错信息会指出问题,对 Python 和 PCRE 写法还会给出 JavaScript 的等价写法。
怎样匹配点号、括号这些特殊字符?
在前面加反斜杠:\. 匹配句点,\( 匹配左括号,\$ 匹配美元符号。方括号里的大多数字符本来就是字面意思,所以 [.] 也能匹配句点。
贪婪和非贪婪有什么区别?
贪婪量词 .* 会尽量多地匹配,所以 <.*> 在 <b>你好</b> 上会匹配整个字符串。加一个 ? 变成非贪婪:<.*?> 遇到第一个 > 就停下,只匹配 <b>。
为什么会出现空匹配?
能匹配“什么都没有”的正则——\d*、x?——在字符之间也会成功。工具用一条细红线标出空匹配。至少需要一个字符时,把 * 换成 +。
最后更新:2026年10月16日