如何提取字符串中指定两个子串之间的所有匹配内容?
解决字符串提取问题:捕获"cow"和"milk"之间的所有文本
嘿,我懂你的困扰!你用string.match('cow (.*?) milk')得到的结果带着完整匹配项,可你只想要捕获组里的内容,还得把所有符合条件的匹配都捞出来,对吧?
为什么原来的方法不生效?
当你不带全局标志g使用match()时,它只会返回第一个匹配项:数组里第一个元素是完整的匹配字符串,后面跟着捕获组的内容——这就是你拿到["cow gives milk", "gives"]的原因。要是加上g,match()会返回所有完整匹配的字符串数组,但会直接忽略捕获组,这也不是你想要的结果。
解决方案1:使用matchAll()(推荐,ES2020+)
matchAll()能返回所有匹配的迭代器,每个迭代项里既包含完整匹配,也保留了捕获组的内容。我们可以用它轻松提取所有目标文本:
const str = "My cow gives milk, my cow always gives milk"; // 注意正则要加上全局标志g const matches = Array.from(str.matchAll(/cow (.*?) milk/g), match => match[1]); console.log(matches); // 输出: ["gives", "always gives"]
这里Array.from()把迭代器转成数组,然后我们从每个匹配项中取出索引为1的元素——也就是我们定义的捕获组(.*?)对应的内容。
解决方案2:循环调用exec()(兼容旧环境)
如果你的运行环境不支持matchAll(),可以用exec()配合循环来实现需求:
const str = "My cow gives milk, my cow always gives milk"; const regex = /cow (.*?) milk/g; const matches = []; let currentMatch; // 循环调用exec()直到没有匹配结果 while ((currentMatch = regex.exec(str)) !== null) { matches.push(currentMatch[1]); } console.log(matches); // 输出: ["gives", "always gives"]
每次调用exec()会返回下一个匹配的结果,我们把捕获组的内容(currentMatch[1])推入数组,直到exec()返回null时结束循环。
内容的提问来源于stack exchange,提问作者lucahuy
相关产品推荐
相关产品推荐

