JavaScript全局正则exec方法交替返回正常值和null是什么原因?
问题原因
带g(全局)修饰符的正则表达式实例会内置维护一个lastIndex属性,该属性记录下一次调用exec()方法时,从目标字符串的哪个下标位置开始搜索。
你提供的示例中,第一次调用exec("s(1, 2)")时,从下标0开始搜索,成功匹配到s(,匹配结束后lastIndex被更新为2;第二次调用时从下标2的位置(对应字符串的1, 2)片段)开始搜索,没有符合规则的匹配结果,因此返回null,此时正则实例会自动将lastIndex重置为0;第三次调用又从下标0开始搜索,匹配成功,以此循环,就出现了交替返回匹配结果和null的现象。
修复方案
根据你的使用场景可以选择以下任意一种方案:
- 方案1:每次匹配前手动重置
lastIndex为0
如果你需要保留正则的g修饰符,可在每次调用exec前重置起始搜索位置:const functionCall = /(?<name>\w+)\((?<s>\))?/g; for(let i = 0; i < 100; i++) { functionCall.lastIndex = 0; const func = functionCall.exec("s(1, 2)"); console.log(func) } - 方案2:移除不需要的
g修饰符
如果你每次都只需要获取目标字符串的第一个匹配结果,不需要全局搜索多匹配项,直接去掉g修饰符即可,无g修饰符的正则不会维护lastIndex,每次调用exec都会默认从下标0开始搜索:const functionCall = /(?<name>\w+)\((?<s>\))?/; for(let i = 0; i < 100; i++) { const func = functionCall.exec("s(1, 2)"); console.log(func) } - 方案3:正确使用全局匹配的写法
如果你确实需要提取目标字符串中所有符合规则的匹配项,使用while循环遍历即可,不要固定循环次数:const functionCall = /(?<name>\w+)\((?<s>\))?/g; const str = "s(1, 2)"; let func; while((func = functionCall.exec(str)) !== null) { console.log(func); }
内容的提问来源于stack exchange,提问作者Григорий Архипов
相关产品推荐
相关产品推荐

