命名捕获组:(?<name>...)
**命名捕获组** 是一种特殊的 捕获组,允许为组命名。稍后可以通过此名称而不是模式中索引来识别组的匹配结果。
语法
正则表达式
(?<name>pattern)
参数
描述
命名捕获组的使用方式与捕获组相同——它们在结果数组中也有其匹配索引,并且可以通过 \1
、\2
等进行引用。唯一的区别是,它们还可以通过其名称进行额外引用。捕获组匹配的信息可以通过以下方式访问
RegExp.prototype.exec()
、String.prototype.match()
和String.prototype.matchAll()
返回值的groups
属性String.prototype.replace()
和String.prototype.replaceAll()
方法的replacement
回调函数的groups
参数- 同一模式内的 命名反向引用
所有名称在同一模式内必须唯一。具有相同名称的多个命名捕获组会导致语法错误。
js
/(?<name>)(?<name>)/; // SyntaxError: Invalid regular expression: Duplicate capture group name
如果重复的命名捕获组不在同一个 析取备选方案 中,则会放宽此限制,因此对于任何字符串输入,实际上只能匹配一个命名捕获组。这是一项更新得多的功能,因此在使用之前请检查 浏览器兼容性。
js
/(?<year>\d{4})-\d{2}|\d{2}-(?<year>\d{4})/;
// Works; "year" can either come before or after the hyphen
所有命名捕获组都将出现在结果中。如果命名捕获组未匹配(例如,它属于析取中未匹配的备选方案),则 groups
对象上的相应属性的值为 undefined
。
js
/(?<ab>ab)|(?<cd>cd)/.exec("cd").groups; // [Object: null prototype] { ab: undefined, cd: 'cd' }
您可以使用 d
标志获取输入字符串中每个命名捕获组的起始和结束索引。除了在 exec()
返回的数组上的 indices
属性上访问它们之外,您还可以通过 indices.groups
上的名称访问它们。
与未命名的捕获组相比,命名捕获组具有以下优点
- 它们允许您为每个子匹配结果提供描述性名称。
- 它们允许您访问子匹配结果,而无需记住它们在模式中出现的顺序。
- 在重构代码时,您可以更改捕获组的顺序,而无需担心破坏其他引用。
示例
使用命名捕获组
以下示例从 Git 日志条目中解析时间戳和作者姓名(使用 git log --format=%ct,%an -- filename
输出)
js
function parseLog(entry) {
const { author, timestamp } = /^(?<timestamp>\d+),(?<author>.+)$/.exec(
entry,
).groups;
return `${author} committed on ${new Date(
parseInt(timestamp) * 1000,
).toLocaleString()}`;
}
parseLog("1560979912,Caroline"); // "Caroline committed on 6/19/2019, 5:31:52 PM"
规范
规范 |
---|
ECMAScript 语言规范 # prod-Atom |
浏览器兼容性
BCD 表仅在启用 JavaScript 的浏览器中加载。