“捕获组”是正则表达式中的概念,除了 JavaScript,在其他正则表达式的应用场景中也都是通用的。下面主要以 JavaScript 中的捕获组为例说明。

首先,在正则表达式中,可以进行“分组”,用一对圆弧括号括起来的表达式就是一个分组。

/(pattern)/ // JS 中分组的基本写法

比如,“/(sun)(day)/”就表示了由“sun”和“day”子表达式构成的两个分组,它最终的匹配效果和“/sunday/”一致,只是分组之后可以将各组子表达式的匹配结果分别处理,操作更加灵活。其实,这两个分组也是捕获组。

捕获组就是将正则表达式中子表达式匹配的结果,分组按顺序保存,之后可以通过序号或名称来使用这些内容。不过,暂时 JavaScript 还不支持为捕获组命名,因此也就无法通过名称来访问捕获组,只能通过序号访问。

下面举3个匹配简单整数四则运算的例子,介绍一下捕获组的基本用法。

1)通过捕获组分别读取前运算数、运算符和后运算数:

var reg1=/(\d+)([\+\-\*\/])(\d+)/;
var matches=reg1.exec("10*20");
var comp=matches[0]; //"10*20"
//序号0为匹配的内容,分组从1开始
var num1=matches[1]; //"10"
var sign=matches[2]; //"*"
var num2=matches[3]; //"20"

捕获组还能反向引用,即在表达式中直接使用某个分组的内容。

2)匹配前、后两个数值的相同情况:

var reg2=/(\d+)([\+\-\*\/])\1/; //反向引用时用“\+序号”即可
var result1=reg2.test("25-25"); //true
var result2=reg2.test("25-14"); //false


3)置换前、后两个数的位置(使用例 1 中的正则表达式):


var str="234/156";
var change=str.replace(reg1,"$3$2$1"); //"156/234"
// 在 replace 语句中引用的写法是“$+序号”


既然有捕获组,那肯定还有非捕获组。顾名思义,只执行 匹配过程、不保存匹 配结果的分组就是非捕获组。在捕获组表达式的左括号后加“?”和“:”等符号即可构成非捕获组 。

/(?:pattern)/ // JS 中非捕获组的基本写法

与非捕获组相关的还有“预查”,这些扩展知识就不多介绍了,感兴趣的话可以自行查找。