JavaScript 正则表达式中的捕获组详解

JavaScript 正则表达式中的捕获组详解

zh.javascript.info 现代 JavaScript 教程(The Modern JavaScript Tutorial),以最新的 ECMAScript 规范为基准,通过简单但足够详细的内容,为你讲解从基础到高阶的 JavaScript 相关知识。 zh.javascript.info 项目地址: https://gitcode.com/gh_mirrors/zh/zh.javascript.info

正则表达式是 JavaScript 中强大的文本处理工具,而捕获组则是正则表达式中一个非常重要的概念。本文将深入讲解捕获组的各种用法和技巧。

什么是捕获组

捕获组是正则表达式中用圆括号 () 括起来的部分,它有两个主要作用:

  1. 将匹配结果中的特定部分单独提取出来
  2. 将括号内的内容视为一个整体应用量词
// 示例:匹配连续的"go"
alert('Gogogo now!'.match(/(go)+/ig)); // 匹配到"Gogogo"

捕获组的基本用法

提取匹配内容

当正则表达式匹配成功后,捕获组的内容会被单独提取出来:

let str = '<h1>Hello, world!</h1>';
let tag = str.match(/<(.*?)>/);

alert(tag[0]); // <h1> (完整匹配)
alert(tag[1]); // h1 (第一个捕获组)

嵌套捕获组

捕获组可以嵌套使用,编号顺序是从左到右按左括号的顺序:

let str = '<span class="my">';
let regexp = /<(([a-z]+)\s*([^>]*))>/;
let result = str.match(regexp);

alert(result[1]); // span class="my" (外层捕获组)
alert(result[2]); // span (标签名)
alert(result[3]); // class="my" (属性)

命名捕获组

ES2018 引入了命名捕获组,可以通过名称而非数字来引用捕获组:

let dateRegexp = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/;
let str = "2019-04-30";
let groups = str.match(dateRegexp).groups;

alert(groups.year);  // 2019
alert(groups.month); // 04
alert(groups.day);   // 30

命名捕获组使代码更易读和维护,特别是在处理复杂正则表达式时。

非捕获组

有时我们需要使用括号分组但不希望捕获内容,这时可以使用非捕获组 (?:...)

let str = "Gogogo John!";
let regexp = /(?:go)+ (\w+)/i;
let result = str.match(regexp);

alert(result[0]); // Gogogo John
alert(result[1]); // John
alert(result.length); // 2 (没有go的捕获组)

使用 matchAll 方法

当需要全局匹配并获取所有捕获组时,可以使用 matchAll 方法:

let str = '<h1> <h2>';
let results = str.matchAll(/<(.*?)>/g);

for(let result of results) {
  alert(result[0]); // 完整匹配
  alert(result[1]); // 捕获组内容
}

matchAll 返回一个迭代器,可以逐个处理每个匹配结果及其捕获组。

在替换中使用捕获组

捕获组可以在替换字符串中引用:

// 交换名字和姓氏
let str = "John Bull";
alert(str.replace(/(\w+) (\w+)/, '$2, $1')); // Bull, John

// 使用命名捕获组
let dateStr = "2019-10-30";
let dateRegexp = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/;
alert(dateStr.replace(dateRegexp, '$<day>.$<month>.$<year>')); // 30.10.2019

实际应用示例

域名匹配

let regexp = /([\w-]+\.)+\w+/g;
alert("site.com my.site.com".match(regexp)); // site.com, my.site.com

电子邮件验证

let regexp = /[-.\w]+@([\w-]+\.)+[\w-]+/g;
alert("my@mail.com @ his@site.com.uk".match(regexp)); // my@mail.com, his@site.com.uk

总结

捕获组是正则表达式中非常强大的功能,掌握它们可以:

  1. 精确提取字符串中的特定部分
  2. 创建更复杂的匹配模式
  3. 在替换操作中重组字符串
  4. 通过命名使正则表达式更易读

记住,简单的模式使用数字编号捕获组即可,复杂的模式则推荐使用命名捕获组以提高可读性。非捕获组则用于只需要分组但不需要提取内容的场景。

zh.javascript.info 现代 JavaScript 教程(The Modern JavaScript Tutorial),以最新的 ECMAScript 规范为基准,通过简单但足够详细的内容,为你讲解从基础到高阶的 JavaScript 相关知识。 zh.javascript.info 项目地址: https://gitcode.com/gh_mirrors/zh/zh.javascript.info

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羿恒新Odette

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值