JavaScript 正则表达式中的捕获组详解
正则表达式是 JavaScript 中强大的文本处理工具,而捕获组则是正则表达式中一个非常重要的概念。本文将深入讲解捕获组的各种用法和技巧。
什么是捕获组
捕获组是正则表达式中用圆括号 ()
括起来的部分,它有两个主要作用:
- 将匹配结果中的特定部分单独提取出来
- 将括号内的内容视为一个整体应用量词
// 示例:匹配连续的"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
总结
捕获组是正则表达式中非常强大的功能,掌握它们可以:
- 精确提取字符串中的特定部分
- 创建更复杂的匹配模式
- 在替换操作中重组字符串
- 通过命名使正则表达式更易读
记住,简单的模式使用数字编号捕获组即可,复杂的模式则推荐使用命名捕获组以提高可读性。非捕获组则用于只需要分组但不需要提取内容的场景。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考