JavaScript正则表达式是RegExp对象而非字符串,字面量(如/\d+/)与构造函数(new RegExp('\\d+'))转义规则不同;test()判断、exec()提取单个(支持捕获组)、match()提取全部(全局时丢失捕获组)。

JavaScript 正则表达式是什么?它不是字符串,是 RegExp 对象
JavaScript 中的正则表达式本质是一个 RegExp 实例,不是普通字符串。虽然可以用字面量写成 /\d+/,也可以用构造函数 new RegExp('\\d+'),但两者在转义和动态构建时行为不同——尤其注意:构造函数的 pattern 参数是字符串,反斜杠需双写,而字面量里单写即可。
常见误解是把 /\d+/ 当作“字符串”,结果在拼接动态内容时出错。比如想匹配用户输入的关键词 keyword,写成 new RegExp('/' + keyword + '/g') 就完全错了——/ 在字符串里只是字符,不会触发正则语法,正确写法是 new RegExp(keyword, 'g')。
用 test()、exec() 和 match() 区分「判断」「提取单个」「提取全部」
三个最常用方法用途明确,混用容易漏数据或报错:
-
test()只返回true/false,适合做条件判断,比如表单校验:/^[a-z0-9_]+$/i.test(username) -
exec()每次只返回第一个匹配及其捕获组(含index、input等属性),全局模式下需循环调用;不加g标志会反复返回第一个结果 -
match()对非全局正则返回数组(含捕获组),对全局正则只返回纯匹配字符串数组,**丢失捕获组信息**;想拿捕获组又需要全部匹配,必须用exec()循环
const str = 'price: $12.99, qty: 5';
const re = /(\w+): \$?(\d+\.\d+)/g;
let result;
while ((result = re.exec(str)) !== null) {
console.log('字段:', result[1], '值:', result[2]);
}
// 输出:字段: price 值: 12.99 → 字段: qty 值: 5
g、i、m 标志的实际影响远不止“全局”“忽略大小写”
标志改变的是正则引擎的匹配逻辑,不是简单开关:
立即学习“Java免费学习笔记(深入)”;
-
g让lastIndex生效,影响exec()和replace()的多次执行;但match()加不加g返回结构完全不同 -
i不仅匹配 ASCII 字母,还覆盖 Unicode 字母(如中文拼音、德语变音符),但对汉字、数字无影响 -
m只有在正则中用了^或$时才起作用——它让这两个锚点匹配每行开头/结尾,而不是整个字符串首尾;没用^/$时加m完全无感
典型陷阱:/^error/i.test('ERROR: timeout') 返回 true,但 /^error/im.test('line1\nERROR: timeout') 仍返回 false,因为换行后 ERROR 不在行首(前面有 \n)。
提取 URL 中的协议、域名、路径,别硬写 split() 或 indexOf()
用正则提取结构化 URL 比手撕字符串更稳,关键是合理使用非贪婪和字符组:
const url = 'https://api.example.com/v1/users?id=123#top';
const match = url.match(/^(\w+):\/\/([^/]+)(\/[^?#]*)?/);
if (match) {
console.log('协议:', match[1]); // https
console.log('域名:', match[2]); // api.example.com
console.log('路径:', match[3] || '/'); // /v1/users
}
注意点:
-
[^/]+比.*?更安全,避免跨到路径部分 -
\/[^?#]*显式排除查询参数和 hash,比\/.*精确 - 括号必须成对,空路径用
(...)?并检查match[3]是否为undefined
真正难的不是写出正则,而是想清楚边界——比如是否允许端口、IPv6 地址、带用户信息的 URL(user:pass@host)。简单场景够用,复杂需求建议用 URL 构造函数解析。











