正则表达式是JavaScript处理字符串的底层基础设施,需掌握字面量与RegExp构造函数两种创建方式、match()/exec()区别、replace()替换规则及test()性能特性。

正则表达式在 JavaScript 中不是“可选技能”,而是处理字符串的底层基础设施——只要涉及提取手机号、验证邮箱、清洗日志、解析 URL 参数,就绕不开 RegExp 对象和字符串的 match()、replace() 等方法。
怎样写一个能用的正则字面量或 RegExp 实例
两种创建方式本质等价,但行为细节不同:
- 字面量写法:
/\d{3}-\d{4}/—— 不能拼接变量,适合静态模式;斜杠间的内容直接被编译,多次使用不重复解析 - 构造函数写法:
new RegExp('\\d{3}-\\d{4}')—— 字符串参数需双转义(JS 字符串一层、正则引擎一层),适合动态生成,比如从用户输入构建搜索模式 - 注意:用
RegExp构造时,标志(如'g'、'i')是第二个参数,不是写在字符串里:new RegExp('abc', 'gi')
match() 和 exec() 的区别:一次匹配 vs 全局循环
match() 是字符串方法,exec() 是正则方法,返回结构不同,影响后续逻辑走向:
-
'123-4567'.match(/\d{3}-\d{4}/)→ 返回数组['123-4567'],含index和input属性;加g标志后只返回匹配项列表,丢失位置信息 -
/\d{3}-\d{4}/.exec('call 123-4567 now')→ 返回完整匹配结果对象,含捕获组;对同一正则实例反复调用exec()可配合g标志做迭代,lastIndex自动推进 - 常见错误:用
match()加g后想取.index,结果是undefined—— 因为全局匹配返回的是纯数组,不是匹配对象
replace() 中的替换值怎么写才不踩坑
replace() 的第二个参数看似简单,实则最容易出错:
立即学习“Java免费学习笔记(深入)”;
- 字符串替换:用
$1、$2引用捕获组,$$表示字面量$;$&是整个匹配项,$`是匹配前内容,$'是匹配后内容 - 函数替换:
str.replace(/(\w+)-(\d+)/, (match, p1, p2) => `${p2}-${p1}`)—— 参数顺序固定:第一个是完整匹配,之后是各捕获组,最后是匹配索引和原字符串 - 陷阱:如果正则没加
g,replace()只换第一个;如果用了函数但忘了返回值,会替换成undefined字符串
为什么 test() 比 match() 更快,但不能替代它
test() 只返回布尔值,内部不构建匹配结果对象,所以开销极小,适合做前置校验:
-
/^\d+$/.test(input)比input.match(/^\d+$/)快,尤其在表单实时验证中差异明显 - 但它不提供匹配内容、位置、分组信息;若后续还需提取数据,别先
test()再match()—— 直接用match()或exec()一次到位 - 注意:带
g标志的正则实例在多次test()调用时会因lastIndex推进而跳过开头,导致偶发失败;要么每次重置regex.lastIndex = 0,要么改用字面量(无状态)
真正难的不是语法,而是理解正则在 JS 中如何与字符串方法协作、状态如何流转、以及哪些边界情况会让 lastIndex、g 标志、捕获组引用同时起作用又互相干扰。这些细节不写进文档,但一出问题就卡半天。











