JavaScript中RegExp exec在for循环中失效问题求助
正则exec遍历数组时最后一项匹配失败的修复方案
问题根源在于你使用了带g(全局匹配)修饰符的正则表达式,exec()方法会维护一个lastIndex属性,记录下一次匹配的起始位置。第一次匹配完第一个字符串后,lastIndex会指向该字符串的末尾;第二次调用exec()处理第二个字符串时,会从这个lastIndex位置开始匹配,自然无法找到结果,返回null。
以下是几种修复方案:
方案1:每次匹配前重置lastIndex
在每次调用exec()前,手动将正则的lastIndex重置为0,确保每次匹配都从字符串开头开始:
let texts = ["Invoice_001_1", "Invoice_001_2"]; var regTest = /(([a-zA-Z 0-9]+)_([0-9]+)_([0-9]+)$|[a-zA-Z ]+_([0-9]+)$)/gi; for(var x=0; x<texts.length; x++) { console.log(texts[x]); regTest.lastIndex = 0; // 重置匹配起始位置 var matchReg = regTest.exec(texts[x]); console.log(matchReg); }
方案2:移除全局匹配修饰符g
因为你的场景是每个字符串只需要匹配一次,g修饰符完全多余。移除后,exec()每次都会从头开始匹配目标字符串:
let texts = ["Invoice_001_1", "Invoice_001_2"]; var regTest = /(([a-zA-Z 0-9]+)_([0-9]+)_([0-9]+)$|[a-zA-Z ]+_([0-9]+)$)/i; for(var x=0; x<texts.length; x++) { console.log(texts[x]); var matchReg = regTest.exec(texts[x]); console.log(matchReg); }
方案3:使用String.match()替代exec()
match()方法针对单个字符串的单次匹配场景更简洁,且不会受lastIndex影响:
let texts = ["Invoice_001_1", "Invoice_001_2"]; var regTest = /(([a-zA-Z 0-9]+)_([0-9]+)_([0-9]+)$|[a-zA-Z ]+_([0-9]+)$)/i; for(var x=0; x<texts.length; x++) { console.log(texts[x]); var matchReg = texts[x].match(regTest); console.log(matchReg); }
额外优化:简化正则表达式
原正则的两个分支存在重叠部分,可以简化为更紧凑的写法,同时保持匹配逻辑不变:
// 使用可选非捕获组合并分支 var regTest = /([a-zA-Z0-9 ]+)_(\d+)(?:_(\d+))?$/i;
内容的提问来源于stack exchange,提问作者bumbumpaw
相关产品推荐
相关产品推荐

