在JavaScript里做字符串校验、内容提取或批量替换时,几乎绕不开RegExp对象。它是正则表达式在JS中的具体实现,既可以写成/abc/g这样的字面量,也可以通过new RegExp()构造函数创建。两种写法效果基本一致,但创建方式、运行时机和适用场景有差别。本文从基础概念讲起,逐步深入到exec、test方法、标志位、lastIndex陷阱以及捕获组的实战用法。

RegExp对象的两种创建方式及其区别
第一种是字面量写法,直接把模式写在两条斜线之间:var reg = /hello/g;。这种写法在脚本解析阶段就会被编译,性能略好,代码也更简洁,适合模式固定的场景。第二种是构造函数写法:var reg = new RegExp("hello", "g");,模式部分是一个字符串,因此在运行时才编译。
构造函数最大的价值在于支持动态拼接。比如你写一个通用的搜索高亮函数,用户输入的关键词事先无法确定,这时只能用构造函数把变量传入。要注意的是,由于模式是字符串形式,反斜杠需要双重转义,匹配一个数字的正则字面量写作/\d/,而构造函数要写成new RegExp("\\d"),这是新手最容易踩的坑之一。
// 字面量方式:模式固定时首选
var reg1 = /^\d{4}-\d{2}-\d{2}$/;
// 构造函数方式:模式需要动态生成
var keyword = "js";
var reg2 = new RegExp(keyword, "gi");
console.log(reg1.test("2024-05-01")); // true
console.log(reg2.test("I love JS")); // true(i标志忽略大小写)test和exec:RegExp自带的两个核心方法
test()方法返回布尔值,只关心是否匹配成功,适合做校验逻辑,例如判断邮箱格式、手机号格式是否合法。它的执行成本较低,不需要关心匹配到的具体内容时优先使用它。
exec()方法则更强大,匹配成功时返回一个数组,第一个元素是匹配到的完整文本,后续元素依次是各个捕获组的内容,同时数组上还带有index(匹配位置)和input(原始字符串)两个属性。匹配失败时返回null。配合g标志位反复调用exec,可以遍历出所有匹配结果。
var str = "订单A100,订单B200,订单C300";
var reg = /订单([A-Z])(\d{3})/g;
var result;
while ((result = reg.exec(str)) !== null) {
console.log("完整匹配:" + result[0]);
console.log("字母编号:" + result[1] + ",金额:" + result[2]);
console.log("位置:" + result.index);
}标志位与lastIndex属性:全局匹配的隐藏陷阱
RegExp对象常用五个标志位:g表示全局匹配,i忽略大小写,m多行匹配(让^和$匹配每一行的开头结尾),y粘性匹配(只从lastIndex位置开始匹配),u启用Unicode模式用于正确处理中文等字符。
这里有一个非常经典的陷阱:带g标志的正则在调用test()或exec()时会修改内部的lastIndex属性。下次调用会从上次结束的位置继续匹配,一旦匹配失败,lastIndex重置为0。如果你在循环或者多次校验中复用同一个全局正则对象,就会出现第一次返回true、第二次返回false的诡异现象。
var reg = /a/g;
console.log(reg.test("abc")); // true,lastIndex变为1
console.log(reg.test("abc")); // false,从位置1继续找,没有a了
console.log(reg.test("abc")); // true,lastIndex已重置为0
// 解决方案:校验场景去掉g标志,或使用字符串字面量内联写法
console.log(/a/g.test("abc")); // 每次都是新的正则对象,恒为true与字符串方法配合使用及实战案例
除了RegExp自身的方法,字符串的match()、replace()、search()、split()都接受正则作为参数。replace()配合g标志可以做批量替换,第二个参数还支持$1、$2这样的反向引用捕获组,或者传入一个函数实现动态替换。
下面给出一个综合案例:从一段文本中提取所有链接并统计手机号出现次数,同时演示动态正则的用法。
var text = "访问 https://ipipp.com 联系13800138000,或拨打13900139000";
// 提取所有手机号
var phones = text.match(/1[3-9]\d{9}/g);
console.log("手机号数量:" + phones.length);
// 动态关键词高亮替换
function highlight(source, keyword) {
var reg = new RegExp(keyword, "g");
return source.replace(reg, function(match) {
return "<strong>" + match + "</strong>";
});
}
console.log(highlight("学习JavaScript很有趣", "JavaScript"));总结一下:模式固定用字面量,模式动态用构造函数;校验用test,提取用exec或match;使用g标志时务必留意lastIndex的状态;复杂替换善用捕获组和函数参数。掌握这几点,RegExp对象就能在你的日常开发中发挥最大价值。
RegExp对象正则表达式JavaScript正则修改时间:2026-09-03 07:36:29