您可以像这样访问捕获组:
var myString = "something format_abc";var myRegexp = /(?:^|s)format_(.*?)(?:s|$)/g;var match = myRegexp.exec(myString);console.log(match[1]); // abc
如果存在多个匹配项,则可以对其进行迭代:
var myString = "something format_abc";var myRegexp = /(?:^|s)format_(.*?)(?:s|$)/g;match = myRegexp.exec(myString);while (match != null) { // matched text: match[0] // match start: match.index // capturing group n: match[n] console.log(match[0]) match = myRegexp.exec(myString);}编辑:2019-09-10
如你所见,迭代多个匹配项的方法不是很直观。这导致了该String.prototype.matchAll方法的提出。这种新方法有望在ECMAscript 2020规范中提供。它为我们提供了一个简洁的API,并解决了多个问题。它已经开始登陆主流浏览器和JS引擎,例如Chrome 73 + / Node 12+和Firefox 67+。
该方法返回一个迭代器,其用法如下:
const string = "something format_abc";const regexp = /(?:^|s)format_(.*?)(?:s|$)/g;const matches = string.matchAll(regexp);for (const match of matches) { console.log(match); console.log(match.index)}当它返回一个迭代器时,我们可以说它是惰性的,这在处理大量捕获组或非常大的字符串时非常有用。但是,如果需要,可以使用 传播语法
或
Array.from方法将结果轻松转换为数组:
function getFirstGroup(regexp, str) { const array = [...str.matchAll(regexp)]; return array.map(m => m[1]);}// or:function getFirstGroup(regexp, str) { return Array.from(str.matchAll(regexp), m => m[1]);}同时,尽管该提案获得了更广泛的支持,但您可以使用官方的shim软件包。
而且,该方法的内部工作很简单。使用生成器功能的等效实现如下:
function* matchAll(str, regexp) { const flags = regexp.global ? regexp.flags : regexp.flags + "g"; const re = new RegExp(regexp, flags); let match; while (match = re.exec(str)) { yield match; }}创建原始正则表达式的副本;这是为了避免
lastIndex在进行多次匹配时由于属性的突变而产生的副作用。
另外,我们需要确保regexp具有 全局 标志以避免无限循环。
我也很高兴看到在提案的讨论中甚至提到了这个StackOverflow问题。



