正则表达式的组匹配

本文介绍了正则表达式的分组匹配概念,通过实例解析括号如何捕获和引用匹配内容,并探讨了非捕获组的使用,用于在不保存分组内容的情况下进行匹配,同时提供了匹配网页标签和分解网址等实用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(1)概述

正则表达式的括号表示分组匹配,括号中的模式可以用来匹配分组的内容。

/zwq+/.test('zwqq') // true
/(zwq)+/.test('zwqzwq') // true

上面代码中,第一个模式没有括号,结果+只表示重复字母q,第二个模式有括号,结果+就表示匹配zwq这个词。

下面是另外一个分组捕获的例子。

var m = 'zwqzwq'.match(/(.)w(.)/);
console.log(m) // ['zwq', 'z', 'q']

上面代码中,正则表达式/(.)b(.)/一共使用两个括号,第一个括号捕获a,第二个括号捕获c。

注意,使用组匹配时,不宜同时使用g修饰符,否则match方法不会捕获分组的内容。

var m = 'zwqzwq'.match(/(.)w(.)/g);
m // ['zwq', 'zwq']

上面代码使用带g修饰符的正则表达式,结果match方法只捕获了匹配整个表达式的部分。这时必须使用正则表达式的exec方法,配合循环,才能读到每一轮匹配的组捕获。

var str = 'abcabc';
var reg = /(.)b(.)/g;
while (true) {
  var result = reg.exec(str);
  if (!result) break;
  console.log(result);
}
// ["abc", "a", "c"]
// ["abc", "a", "c"]

正则表达式内部,还可以用\n引用括号匹配的内容,n是从1开始的自然数,表示对应顺序的括号。

    /(.)b(.)\1b\2/.test("abcabc")
    // true

上面的代码中,\1表示第一个括号匹配的内容(即a),\2表示第二个括号匹配的内容(即c)。

下面是另外一个例子。

/y(..)(.)\2\1/.test('yabccab') // true

括号还可以嵌套。

/y((..)\2)\1/.test('yabababab') // true

上面代码中,\1指向外层括号,\2指向内层括号。

组匹配非常有用,下面是一个匹配网页标签的例子。

var tagName = /<([^>]+)>[^<]*<\/\1>/;

tagName.exec("<b>bold</b>")[1]
// 'b'

上面代码中,圆括号匹配尖括号之中的标签,而\1就表示对应的闭合标签。

上面代码略加修改,就能捕获带有属性的标签。

var html = '<b class="hello">Hello</b><i>world</i>';
var tag = /<(\w+)([^>]*)>(.*?)<\/\1>/g;

var match = tag.exec(html);

match[1] // "b"
match[2] // " class="hello""
match[3] // "Hello"

match = tag.exec(html);

match[1] // "i"
match[2] // ""
match[3] // "world"

(2)非捕获组

(?:x)称为非捕获组(Non-capturing group),表示不返回该组匹配的内容,即匹配的结果中不计入这个括号。

非捕获组的作用请考虑这样一个场景,假定需要匹配foo或者foofoo,正则表达式就应该写成/(foo){1, 2}/,但是这样会占用一个组匹配。这时,就可以使用非捕获组,将正则表达式改为/(?:foo){1, 2}/,它的作用与前一个正则是一样的,但是不会单独输出括号内部的内容。

请看下面的例子。

var m = 'abc'.match(/(?:.)b(.)/);
m // ["abc", "c"]

上面代码中的模式,一共使用了两个括号。其中第一个括号是非捕获组,所以最后返回的结果中没有第一个括号,只有第二个括号匹配的内容。

下面是用来分解网址的正则表达式。

// 正常匹配
var url = /(http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/;

url.exec('http://google.com/');
// ["http://google.com/", "http", "google.com", "/"]

// 非捕获组匹配
var url = /(?:http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/;

url.exec('http://google.com/');
// ["http://google.com/", "google.com", "/"]

上面的代码中,前一个正则表达式是正常匹配,第一个括号返回网络协议;后一个正则表达式是非捕获匹配,返回结果中不包括网络协议。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值