使用exec()循环获取匹配项位置需启用g标志,通过返回数组的index和[0]属性计算起始与结束位置,input属性提供原始字符串,标准while循环自动推进lastIndex。

使用 exec() 循环获取匹配项的详细位置信息,关键在于每次调用后检查返回数组的 index 属性和 input 属性,并确保正则表达式带有 g(全局)标志。
必须启用全局模式(g)
若正则未带 g 标志,exec() 每次都从字符串开头匹配,无法推进 lastIndex,也就无法循环遍历后续匹配项。
- 正确写法:
/pattern/g或new RegExp('pattern', 'g') - 错误写法:
/pattern/(无 g)——只返回第一个匹配,反复调用结果不变
利用返回数组的 index 和 0 元素定位
exec() 返回的数组是“类数组对象”,除捕获内容外,自带两个重要属性:
-
index:当前匹配项在原字符串中的起始下标(从 0 开始) -
[0]:完整匹配的字符串,长度可算出结束位置:index + [0].length -
input:原始输入字符串(可用于验证或上下文提取)
例如:const r = /\w+/g; const m = r.exec('Hello world!'); → m.index === 0, m[0] === 'Hello', 结束位置为 5。
手动控制 lastIndex(进阶场景)
正常循环中无需手动改 lastIndex,但若需跳过某些匹配、回退或注入逻辑,可直接读写正则实例的 lastIndex 属性:
- 读取:
regex.lastIndex表示下次匹配的起始位置 - 修改:
regex.lastIndex = n可强制下一次从位置n开始匹配(需确保n ≤ str.length) - 注意:仅对带
g或y标志的正则有效;不带时设置无效
标准循环写法(推荐)
最稳妥的循环结构如下,自动处理 lastIndex 推进与终止:
const regex = /(\d+)-(\w+)/g;
const str = 'id:123-a, code:456-b';
let match;
while ((match = regex.exec(str)) !== null) {
console.log({
value: match[0], // 完整匹配:'123-a'
group1: match[1], // 第一捕获组:'123'
group2: match[2], // 第二捕获组:'a'
start: match.index, // 起始位置:4
end: match.index + match[0].length, // 结束位置(不包含):10
input: match.input // 原字符串
});
}
该写法天然支持所有捕获组、正确更新状态,且兼容空匹配(如 /a*/g)等边界情况。

















