JavaScript正则需理解执行上下文、修饰符作用域及方法差异:字面量适合静态规则,RegExp构造函数用于动态生成(注意双反斜杠);match/exec/test返回值不同;g全局匹配、y粘性匹配需配合exec使用。

JavaScript 中正则表达式不是“学完就一劳永逸”的工具,用错地方或写错语法会直接导致匹配失败、死循环甚至页面卡死。关键不在会不会写 /abc/,而在于是否理解执行上下文、修饰符作用域和方法返回值差异。
RegExp 构造函数 vs 字面量写法:什么时候必须用 new RegExp()
字面量 /pattern/flags 在脚本加载时就编译,适合静态规则;构造函数 new RegExp(pattern, flags) 支持动态拼接,但要注意反斜杠要双写(因为字符串先解析一次)。
常见错误:想匹配 \d+ 却写成 new RegExp("\d+") → 实际传入的是 d+(\d 被字符串转义吃掉了)。正确写法是 new RegExp("\\d+") 或用模板字符串避开:new RegExp(`\\d+`)。
- 需要从变量、用户输入或 API 响应中生成正则时,必须用
new RegExp() - 全局匹配
g修饰符下,字面量正则有lastIndex状态,多次调用exec()会继续上次位置;构造函数每次新建实例,lastIndex总是 0 - 性能上,字面量略快,但差异微乎其微,优先按可读性和需求选
match()、exec()、test() 的返回值陷阱
这三个方法看着像,行为却完全不同:match() 是字符串方法,exec() 和 test() 是正则对象方法,且返回结构天差地别。
立即学习“Java免费学习笔记(深入)”;
典型翻车现场:"abc123".match(/\d+/) 返回 ["123"],但加了 g 修饰符后变成 ["123"](没错,还是数组);而 /\d+/.exec("abc123") 永远只返回第一个匹配的详细信息(含 index、input),/\d+/.test("abc123") 只返回 true 或 false。
- 只关心“有没有匹配”:用
test(),它不构建匹配数组,性能最好 - 需要捕获组内容或匹配位置:用
exec(),尤其配合g循环调用获取所有结果 - 想一行拿到全部匹配字符串(无捕获细节):用
match(),但注意null返回值需判空
g 和 y 修饰符的区别:全局匹配不是简单“找全”
g(global)让正则反复查找,直到串尾;y(sticky)强制从 lastIndex 开始匹配,且不跳过中间字符——它更像“粘性锚点”,常用于词法分析。
比如 /(a|b)+/y.exec("abac"):第一次匹配 "ab"(lastIndex=2),第二次从索引 2 开始,面对 "ac",a 能匹配,但后面是 c 不在 (a|b) 中,所以失败,不会退回去尝试只匹配一个 a。
- 普通遍历匹配用
g就够了,y使用场景极窄,除非你在手写解析器 -
y必须配合exec(),match()不支持它 - 忘了重置
lastIndex = 0就重复使用同一个正则实例,y会直接从上次断点继续,容易漏开头
真正难的不是写出一个能跑的正则,而是当它在线上突然不匹配、或匹配过长时,你能快速定位是修饰符冲突、贪婪模式误伤,还是字符串编码里混进了不可见字符。多打几次 console.log(RegExp.lastMatch) 和检查 reg.lastIndex,比背语法表管用得多。











