捕获组

120 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情

模式的一部分可以用括号括起来 (...)。这被称为“捕获组(capturing group)”。

这有两个影响:

  1. 它允许将匹配的一部分作为结果数组中的单独项。
  2. 如果我们将量词放在括号后,则它将括号视为一个整体。

示例

让我们看看在示例中的括号是如何工作的。

示例:gogogo

不带括号,模式 go+ 表示 g 字符,其后 o 重复一次或多次。例如 goooo 或 gooooooooo

括号将字符组合,所以 (go)+ 匹配 gogogogogogo等。

alert( 'Gogogo now!'.match(/(go)+/i) ); // "Gogogo"

示例:域名

让我们做些更复杂的事 —— 搜索域名的正则表达式。

例如:

mail.com
users.mail.com
smith.users.mail.com

正如我们所看到的,一个域名由重复的单词组成,每个单词后面有一个点,除了最后一个单词。

在正则表达式中是 (\w+.)+\w+

let regexp = /(\w+.)+\w+/g;

alert( "site.com my.site.com".match(regexp) ); // site.com,my.site.com

搜索有效,但该模式无法匹配带有连字符的域名,例如 my-site.com,因为连字符不属于 \w 类。

我们可以通过用 [\w-] 替换 \w 来匹配除最后一个单词以外的每个单词:([\w-]+.)+\w+

示例:电子邮件

扩展一下上面这个示例。我们可以基于它为电子邮件创建一个正则表达式。

电子邮件的格式为:name@domain。名称可以是任何单词,允许使用连字符和点。在正则表达式中为 [-.\w]+

模式:

let regexp = /[-.\w]+@([\w-]+.)+[\w-]+/g;

alert("my@mail.com @ his@site.com.uk".match(regexp)); // my@mail.com, his@site.com.uk

该正则表达式并不完美的,但多数情况下都能正确匹配,并且有助于修复输入邮箱时的意外错误输入。唯一真正可靠的电子邮件检查只能通过发送电子邮件来完成。

匹配中的括号的内容

括号被从左到右编号。正则引擎会记住它们各自匹配的内容,并允许在结果中获取它。

方法 str.match(regexp),如果 regexp 没有修饰符 g,将查找第一个匹配项,并将它作为数组返回:

  1. 在索引 0 处:完整的匹配项。
  2. 在索引 1 处:第一个括号的内容。
  3. 在索引 2 处:第二个括号的内容。
  4. ……等等……

例如,我们想找到 HTML 标签 <.*?> 并处理它们。将标签内容(尖括号内的内容)放在单独的变量中会很方便。

让我们将内部内容包装在括号中,像这样:<(.*?)>

现在,我们在结果数组中得到了标签的整体 <h1> 及其内容 h1

let str = '<h1>Hello, world!</h1>';

let tag = str.match(/<(.*?)>/);

alert( tag[0] ); // <h1>
alert( tag[1] ); // h1

嵌套组

括号可以嵌套。在这种情况下,编号也从左到右。

例如,在搜索标签 <span class="my"> 时,我们可能会对以下内容感兴趣:

  1. 整个标签的内容:span class="my"
  2. 标签名称:span
  3. 标签特性:class="my"

让我们为它们添加括号:<(([a-z]+)\s*([^>]*))>

这是它们的编号方式(根据左括号从左到右):

验证:

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"

result 的索引 0 中始终保存的是正则表达式的完整匹配项。

然后是按左括号从左到右编号的组。第一组返回为 result[1]。它包含了整个标签内容。

然后是 result[2],从第二个左括号开始分组 ([a-z]+) —— 标签名称,然后在 result[3] 中:([^>]*)

字符串中每个组的内容