捕获组: (...)
**捕获组**对子模式进行分组,允许您将量词应用于整个组或在其中使用析取。它记住有关子模式匹配的信息,以便您可以使用反向引用稍后引用它,或通过匹配结果访问信息。
如果您不需要子模式匹配的结果,请改用非捕获组,这可以提高性能并避免重构风险。
语法
(pattern)
参数
描述
捕获组的作用类似于 JavaScript 表达式中的分组运算符,允许您将子模式用作单个原子。
捕获组按其开括号的顺序编号。第一个捕获组编号为1
,第二个编号为2
,依此类推。命名捕获组也是捕获组,并与其他(未命名)捕获组一起编号。捕获组匹配的信息可以通过以下方式访问
RegExp.prototype.exec()
、String.prototype.match()
和String.prototype.matchAll()
的返回值(这是一个数组)String.prototype.replace()
和String.prototype.replaceAll()
方法的replacement
回调函数的pN
参数- 同一模式中的反向引用
注意:即使在exec()
的结果数组中,捕获组也是通过数字1
、2
等访问的,因为0
元素是整个匹配。\0
不是反向引用,而是字符转义,用于 NUL 字符。
正则表达式源代码中的捕获组与其结果一一对应。如果捕获组未匹配(例如,它属于析取中未匹配的备选方案),则相应的结果为undefined
。
/(ab)|(cd)/.exec("cd"); // ['cd', undefined, 'cd']
捕获组可以量化。在这种情况下,与该组对应的匹配信息是该组的最后一个匹配。
/([ab])+/.exec("abc"); // ['ab', 'b']; because "b" comes after "a", this result overwrites the previous one
捕获组可用于前瞻和后顾断言。由于后顾断言向后匹配其原子,因此与该组对应的最终匹配是出现在字符串左侧末尾的匹配。但是,匹配组的索引仍然与其在正则表达式源代码中的相对位置相对应。
/c(?=(ab))/.exec("cab"); // ['c', 'ab']
/(?<=(a)(b))c/.exec("abc"); // ['c', 'a', 'b']
/(?<=([ab])+)c/.exec("abc"); // ['c', 'a']; because "a" is seen by the lookbehind after the lookbehind has seen "b"
捕获组可以嵌套,在这种情况下,外部组首先编号,然后是内部组,因为它们按其开括号排序。如果嵌套组由量词重复,则每次组匹配时,子组的结果都会被全部覆盖,有时会使用undefined
。
/((a+)?(b+)?(c))*/.exec("aacbbbcac"); // ['aacbbbcac', 'ac', 'a', undefined, 'c']
在上面的示例中,外部组匹配了三次
- 匹配
"aac"
,子组为"aa"
、undefined
和"c"
。 - 匹配
"bbbc"
,子组为undefined
、"bbb"
和"c"
。 - 匹配
"ac"
,子组为"a"
、undefined
和"c"
。
第二次匹配的"bbb"
结果未保留,因为第三次匹配将其覆盖为undefined
。
您可以通过使用d
标志获取输入字符串中每个捕获组的起始和结束索引。这会在exec()
返回的数组上创建一个额外的indices
属性。
您可以选择为捕获组指定名称,这有助于避免与组位置和索引相关的陷阱。有关更多信息,请参阅命名捕获组。
括号在不同的正则表达式语法中具有其他用途。例如,它们还包含前瞻和后顾断言。由于这些语法都以?
开头,而?
是一个量词,它通常不能直接出现在(
之后,因此不会导致歧义。
示例
匹配日期
以下示例匹配格式为YYYY-MM-DD
的日期
function parseDate(input) {
const parts = /^(\d{4})-(\d{2})-(\d{2})$/.exec(input);
if (!parts) {
return null;
}
return parts.slice(1).map((p) => parseInt(p, 10));
}
parseDate("2019-01-01"); // [2019, 1, 1]
parseDate("2019-06-19"); // [2019, 6, 19]
配对引号
以下函数匹配字符串中的title='xxx'
和title="xxx"
模式。为了确保引号匹配,我们使用反向引用来引用第一个引号。访问第二个捕获组([2]
)将返回匹配引号字符之间的字符串
function parseTitle(metastring) {
return metastring.match(/title=(["'])(.*?)\1/)[2];
}
parseTitle('title="foo"'); // 'foo'
parseTitle("title='foo' lang='en'"); // 'foo'
parseTitle('title="Named capturing groups\' advantages"'); // "Named capturing groups' advantages"
规范
规范 |
---|
ECMAScript 语言规范 # prod-Atom |
浏览器兼容性
BCD 表格仅在浏览器中加载