JavaScript正则表达式需关注构造方式(字面量或RegExp构造函数)、标志位组合及方法选择;test()返回布尔值,exec()返回匹配详情且具状态;match()行为取决于g标志,全局匹配推荐matchAll();注意点号、贪婪、Unicode和flag冲突等陷阱。

JavaScript 正则表达式不是“写出来就能用”,关键在 RegExp 实例的构造方式、标志位组合,以及匹配方法(test()、exec()、match() 等)的选择是否匹配你的目标场景。
怎么创建一个有效的正则表达式对象
两种写法:字面量和构造函数。字面量更常用,但动态拼接时必须用 RegExp 构造函数。
- 字面量:
/\d{3}-\d{4}/—— 不能拼变量,斜杠间不能有空格,转义用\\ - 构造函数:
new RegExp('\\d{3}-\\d{4}')—— 字符串里反斜杠要双写,否则会被 JS 字符串解析吃掉一层 - 带标志位:
/abc/gi等价于new RegExp('abc', 'gi');但new RegExp('abc', 'g' + 'i')也合法
test() 和 exec() 的核心区别在哪
test() 只返回布尔值,适合做“是否存在匹配”判断;exec() 返回匹配详情(含 index、groups),且对全局正则有状态(lastIndex),多次调用会继续往后找。
- 用
test()判断邮箱格式:/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) - 用
exec()提取所有数字:const re = /\d+/g; let m; while ((m = re.exec(str)) !== null) { console.log(m[0]); } - ⚠️ 全局正则被多个
exec()复用时,lastIndex不重置会导致漏匹配 —— 建议每次用前手动设re.lastIndex = 0,或改用str.match(re)
为什么 match() 有时返回 null,有时是数组
match() 行为取决于正则是否带 g 标志:
立即学习“Java免费学习笔记(深入)”;
- 无
g:返回第一个匹配的详细信息数组(含index、input),没匹配则null - 有
g:只返回纯匹配字符串数组,不带位置信息;捕获组全丢弃 - 想同时拿到全局匹配 + 捕获组?别用
match(),改用matchAll()(ES2020+):[...str.matchAll(/(\d+)-(\d+)/g)]返回迭代器,每个元素是带分组的数组
常见陷阱:点号、贪婪、Unicode 和 flag 冲突
点号 . 默认不匹配换行符,^/$ 默认只认字符串首尾,\w 不包含中文 —— 这些都容易误判。
- 让
.匹配换行:/pattern/s(sflag,又称“dotAll”);没这个 flag 时用[\s\S]替代 - 避免过度贪婪:
.*会吞到最右再回退;要最小匹配就加?:.*?或\w+? - 匹配中文等 Unicode 字符:
/\p{Script=Han}/u(需uflag),普通\w在中文环境基本失效 -
g和y(sticky)不能共存;m(多行)让^/$匹配每行起止,不是整个字符串
真正难的不是写出一个能跑的正则,而是预判它在边界输入(空字符串、特殊符号、超长文本、不同编码)下的行为 —— 尤其是全局模式复用、标志位叠加、Unicode 处理这三块,最容易在线上突然出错。











