非捕获组:(?:...)

基线 广泛可用

此功能已得到很好的建立,并且可在许多设备和浏览器版本上运行。它自以下时间起在所有浏览器中都可用 2015 年 7 月.

**非捕获组**对子模式进行分组,允许您将量词应用于整个组或在其中使用析取。它类似于 JavaScript 表达式中的分组运算符,并且与捕获组不同,它不会记住匹配的文本,从而提高性能并避免模式也包含有用的捕获组时产生的混淆。

语法

正则表达式
(?:pattern)

参数

模式

由您可能在正则表达式字面量中使用的任何内容组成的模式,包括析取

示例

对子模式进行分组并应用量词

在以下示例中,我们测试文件路径是否以styles.cssstyles.[a hex hash].css结尾。因为整个\.[\da-f]+部分是可选的,所以为了将?量词应用于它,我们需要将其分组为一个新的原子。使用非捕获组通过不创建我们不需要的额外匹配信息来提高性能。

js
function isStylesheet(path) {
  return /styles(?:\.[\da-f]+)?\.css$/.test(path);
}

isStylesheet("styles.css"); // true
isStylesheet("styles.1234.css"); // true
isStylesheet("styles.cafe.css"); // true
isStylesheet("styles.1234.min.css"); // false

对析取进行分组

析取在正则表达式中具有最低优先级。如果您想将析取用作更大模式的一部分,则必须对其进行分组。除非您依赖于析取的匹配文本,否则建议您使用非捕获组。以下示例使用与输入边界断言文章相同的代码匹配文件扩展名

js
function isImage(filename) {
  return /\.(?:png|jpe?g|webp|avif|gif)$/i.test(filename);
}

isImage("image.png"); // true
isImage("image.jpg"); // true
isImage("image.pdf"); // false

避免重构风险

捕获组通过其在模式中的位置进行访问。如果您添加或删除捕获组,则还必须更新其他捕获组的位置,如果您是通过匹配结果或反向引用访问它们。这可能是错误的根源,尤其是在大多数组纯粹用于语法目的(应用量词或分组析取)时。使用非捕获组可以避免此问题,并允许轻松跟踪实际捕获组的索引。

例如,假设我们有一个函数匹配字符串中的title='xxx'模式(示例取自捕获组)。为了确保引号匹配,我们使用反向引用来引用第一个引号。

js
function parseTitle(metastring) {
  return metastring.match(/title=(["'])(.*?)\1/)[2];
}

parseTitle('title="foo"'); // 'foo'

如果我们稍后决定添加name='xxx'作为title=的别名,我们将需要将析取分组到另一个组中

js
function parseTitle(metastring) {
  // Oops — the backreference and index access are now off by one!
  return metastring.match(/(title|name)=(["'])(.*?)\1/)[2];
}

parseTitle('name="foo"'); // Cannot read properties of null (reading '2')
// Because \1 now refers to the "name" string, which isn't found at the end.

与其查找所有引用捕获组索引的位置并逐一更新它们,不如避免使用捕获组

js
function parseTitle(metastring) {
  // Do not capture the title|name disjunction
  // because we don't use its value
  return metastring.match(/(?:title|name)=(["'])(.*?)\1/)[2];
}

parseTitle('name="foo"'); // 'foo'

命名捕获组是避免重构风险的另一种方法。它允许通过自定义名称访问捕获组,当添加或删除其他捕获组时,该名称不受影响。

规范

规范
ECMAScript 语言规范
# prod-Atom

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅