为何JavaScript正则exec匹配结果返回undefined数组?
为什么你得到的是
[undefined, undefined, undefined] 嘿,我来帮你拆解下问题出在哪:
1. 非捕获组不会存储匹配内容
你写的正则里用了 (?:[^ ]+ ){0,3} 和 (?: [^ ]+){0,3},这里的 ?: 表示这是非捕获组——它只会帮你定义匹配的规则,但不会把匹配到的内容存到捕获组(也就是 match[1]、match[2] 这类位置)里。
每次调用 re.exec() 返回的 match 数组里,只有 match[0] 是完整的匹配结果,match[1] 根本不存在,所以你取它的时候自然就是 undefined。
2. 循环里错误提取了不存在的捕获项
你在循环里执行 matches.push(match[1]),但因为没有捕获组,match[1] 始终是 undefined,所以最终数组里全是这个值。
修复方案,拿到你想要的结果
根据你的需求(提取包含 test 的前后3个单词的片段),有两种简单的修复方式:
方式1:直接提取完整匹配结果(最省事)
如果你只需要包含 test 的整个片段,完全不用改正则,把 match[1] 换成 match[0] 就行;另外判断循环结束时建议用 match !== null(因为 re.exec() 没匹配到的时候返回的是 null,不是 undefined,这样更严谨):
const search = "test"; const regexString = "(?:[^ ]+ ){0,3}" + search + "(?: [^ ]+){0,3}"; const re = new RegExp(regexString, "gi"); const matches = []; const fullText = "my test string with a lot of tests that should match the test regex"; let match = re.exec(fullText); while (match !== null) { matches.push(match[0]); match = re.exec(fullText); } console.log(matches);
运行后会得到你想要的结果:
[ 'my test string with', 'of tests that should', 'the test regex' ]
方式2:改用捕获组(如果需要单独提取前后内容)
要是你之后需要把 test 和前后的文本分开处理,可以把非捕获组改成捕获组(去掉 ?:),这样就能单独提取前后的内容了:
const search = "test"; // 把前后的非捕获组改成捕获组,也可以给整个匹配加个捕获组 const regexString = "((?:[^ ]+ ){0,3})" + search + "((?: [^ ]+){0,3})"; const re = new RegExp(regexString, "gi"); const matches = []; const fullText = "my test string with a lot of tests that should match the test regex"; let match = re.exec(fullText); while (match !== null) { // 现在 match[1] 是 test 前面的内容,match[2] 是后面的内容 matches.push({ 完整片段: match[0], 前面内容: match[1].trim(), 后面内容: match[2].trim() }); match = re.exec(fullText); } console.log(matches);
这个版本会返回结构化的结果,方便你单独处理前后的文本。
内容的提问来源于stack exchange,提问作者Mary
相关产品推荐
相关产品推荐

