捕获组
模式的一部分可以用括号括起来 (…)。这称为“捕获组(capturing group)
1、它允许将匹配的一部分作为结果数组中的单独项
2、如果我们将量词放到括号后,则他将括号视为一个整体
示例:gogogo
不带括号,模式 go+ 表示 g 字符,其后 o 重复一次或多次。例如 goooo 或 gooooooooo。
括号将字符组合,所以 (go)+ 匹配 go,gogo,gogogo等。
alert( 'Gogogo now!'.match(/(go)+/i) ); // "Gogogo"
示例
搜索域名的正则表达式
mail.com
users.mail.com
smith.users.mail.com
一个域名由重复的单词组成,每个单词后面有一个点,除了最后一个单词
let regexp = /([\w-]+\.)+\w+/g;
alert( "site.com my.site.com".match(regexp) ); // site.com,my.site.com
匹配括号的内容
括号从左到右编号。正则引擎会记住它们各自匹配的内容,并允许在结果中获得它。
方法 str.match(regexp)
,如果 regexp 没有 g 标志,将查找第一个匹配并将它作为一个数组返回:
在索引 0 处:完全匹配。
在索引 1 处:第一个括号的内容。
在索引 2 处:第二个括号的内容。
…等等…
我们想找到 HTML 标记 <.?> 并进行处理。这将很方便的把标签内容(尖括号内的内容)放在单独的变量中
我们将内部内容包装在括号中,像这样:<(.?)>。
这样就可以获得标签的整体以及标签的内容
let str = '<h1>Hello, world!</h1>';
let tag = str.match(/<(.*?)>/);
alert( tag[0] ); // <h1>
alert( tag[1] ); // h1
嵌套组
可选组
即使组是可选的并且在匹配项中不存在(例如,具有数量词 (…)?),也存在相应的 result 数组项,并且等于 undefined。
括号可以嵌套。在这种情况下,编号也从左到右。
let str = '<span class="my">';
let regexp = /<(([a-z]+)\s*([^>]*))>/;
let result = str.match(regexp);
alert(result[0]); // <span class="my">
alert(result[1]); // span class="my"
alert(result[2]); // span
alert(result[3]); // class="my"
matchAll函数返回的不是数组,而是一个可迭代的对象
非捕获组:可以通过在开头添加 ?: 来排除组。
命名组:
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 dateRegexp = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/g;
let str = "2019-10-30 2020-01-01";
let results = str.matchAll(dateRegexp);
for(let result of results) {
let {year, month, day} = result.groups;
alert(`${day}.${month}.${year}`);
// 第一个 alert:30.10.2019
// 第二个:01.01.2020
}
方法str.replace(regexp, replacement) 用 replacement 替换 str 中匹配 regexp 的所有捕获组。这使用 $n 来完成,其中 n 是组号。