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

Baseline 已广泛支持

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

非捕获组将子模式分组,允许你对整个组应用量词,或在其中使用或运算符。它的作用类似于 JavaScript 表达式中的分组运算符,与捕获组不同,它不记住匹配的文本,从而提供更好的性能,并避免当模式中也包含有用的捕获组时造成的混淆。

语法

正则表达式
(?:pattern)

参数

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® 2026 语言规范
# prod-Atom

浏览器兼容性

另见