JavaScript正则关键在于正确选择字面量或RegExp构造函数、区分exec/match返回结构、警惕g标志缺失导致静默失败;静态模式用字面量,动态变量需RegExp并转义特殊字符;需捕获组+全局遍历时用exec,取全部匹配用matchAll,替换复杂逻辑用函数参数。

JavaScript 里用正则表达式做文本处理,关键不是“会不会写正则”,而是「什么时候该用 RegExp 构造函数,什么时候直接写字面量」、「exec 和 match 返回结构为什么总搞混」、「全局标志 g 不加会静默失败」。
字面量 vs RegExp 构造函数:别在运行时拼接正则
字面量写法(如 /\d+/g)在代码加载时就编译好,性能好、可读性强;RegExp 构造函数(如 new RegExp('\\d+', 'g'))适合模式动态生成。但注意:字符串转义要翻倍——'\\d+' 才能表示一个 \d+,漏掉一个反斜杠就会匹配字面的 d+。
- 静态模式(比如校验邮箱、提取日期)→ 优先用字面量
- 模式含变量(比如搜索用户输入的关键词)→ 必须用
RegExp,且对变量内容做replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')转义 - 不要写
new RegExp('/\\d+/g')—— 斜杠和标志是字面量语法,构造函数里传了就是错的
exec 和 test:需要反复匹配或带状态时才用
exec 是唯一能配合 g 标志「记住上次位置」的方法,适合循环提取所有匹配;test 只返回布尔值,但会偷偷修改 lastIndex(尤其在共享正则对象时容易出错)。不用 g 时,exec 和 test 行为稳定;加了 g 就得小心重用同一个正则实例。
- 只判断是否存在 → 用
test,但别复用带g的正则对象 - 要取全部匹配结果 → 用
match或matchAll(见下条),别手写exec循环 - 必须用
exec的场景:需要捕获组 + 全局遍历 + 同时访问index和input属性
match、matchAll、replace:日常文本处理主力
match 在无 g 时返回带捕获组的数组([fullMatch, group1, group2]),有 g 时只返回纯匹配字符串数组(丢弃分组);matchAll 总是返回迭代器,每个元素都是完整 exec 结果,安全又清晰;replace 的第二个参数可以是字符串(支持 引用捕获组)或函数(参数依次为匹配全文、各捕获组、起始索引、原字符串)。
立即学习“Java免费学习笔记(深入)”;
- 想拿所有匹配 + 捕获内容 → 用
matchAll,别用match加g - 替换逻辑简单(比如统一换前缀)→ 字符串替换,如
'abc'.replace(/^/, 'X-') - 替换依赖匹配内容(比如把数字乘以 2)→ 用函数替换:
'a1b2'.replace(/(\d)/g, (_, d) => +d * 2)
常见陷阱:标志、Unicode、边界问题
g(全局)、i(忽略大小写)、m(多行)三个标志最常用,但 u(Unicode)容易被忽略:没有它,\w 不匹配中文,. 不匹配 emoji,^/$ 在换行符处行为异常;y(粘性)几乎没人用,除非你真在模拟流式解析。
- 处理中文、emoji、生僻字 → 正则开头加
u,比如/\p{Script=Han}/u - 想匹配单词边界但含中文 →
\b失效,改用(? 或直接按需切分 -
^和$默认只匹配整个字符串首尾,多段文本每行都要匹配?加m标志
真正难的不是写出一个能跑的正则,而是当它在线上突然不匹配、或无限循环(回溯爆炸)时,你能快速定位是标志没开、转义漏了、还是 Unicode 边界没对齐。











