分组的使用场景
在书写正则表达式时,通常情况下,我们有两种场景会使用到分组。 一是:对一个子表达式进行重复;二是:想要获取到子表达式匹配到的内容。
- 对子表达式进行重复
如果需要重复单个字符,直接在字符后面加上限定符即可,例如 a+
表示匹配1个或一个以上的a,a?
表示匹配0个或1个a。
但是我们如果要对多个字符进行重复的话,就需要用到 分组 。
比如:(ab){3}
表示 ab 字符重复3次
正则中常用的限定符如下:
表达式 说明 X ? X ,一次或一次也没有 X * X ,零次或多次 X + X ,一次或多次 X { n } X ,恰好 n 次 X { n ,} X ,至少 n 次 X { n , m } X ,至少 n 次,但是不超过 m 次
- 获取到子表达式匹配到的内容
比如表达式: [a-z]*\d*[a-z]*
,它表示a-z的字符重复0到多次,后面紧跟0到多个数字,后面再跟上多个a-z的字符。
显然,字符串 abcd324232efg
是满足匹配的串。那么,如果我们只想要获取到匹配串中数字 324232
后面的串 efg
呢?
这时,就可以通过分组的方式来改写正则表达式: [a-z]*\d*([a-z]*)
。这样,我们就可以通过获取第 1 个分组匹配到的内容来达到目的。
分组的使用方法
正则中通过小括号“()”
来指定需要重复的子表达式,然后再加上限定符对这个子表达式进行重复。
例如:(abc)? 表示0个或1个abc 。 一组括号里面的表达式就表示一个分组 。
捕获组
分组可以分为两种形式,捕获组和非捕获组。
捕获组和非捕获组的区别就是:捕获组表示的分组会捕获文本(即:匹配字符),而非捕获组表示的分组不会捕获文本。
捕获组可以通过从左到右计算其开括号来编号 。 例如,在表达式 (A)(B(C)) 中,存在四个这样的组:
分组编号 | 分组编号对应的子表达式 |
---|---|
(A)(B(C)) | |
1 | (A) |
2 | (B(C)) |
3 | (C) |
注意:第0个分组始终代表整个表达式
分组的序号可以通过 Back 引用(反向引用) 在表达式中使用,也可以在匹配操作完成后从匹配器检索出分组匹配到的内容。 反向引用的知识将会在后续的文章中进行分析。
分组的使用实例
在一个完整的正则中,如果我们只想获取到某个子表达式匹配到的内容,就可以通过分组来达到目的。
比如:
待匹配串:abcd324232efg
想要获取到这个字符串中第二次连续出现的字母子串efg
我们可以通过分组的方式书写正则: [a-z]*\d*([a-z]*)
。
可以看到,我们通过子表达式([a-z]*)
来匹配第二次连续出现之母的子串,并且通过()
添加了分组,这样,我们就可以通过分组来获取到相应的匹配内容了。
具体的获取方法不同的语言的语法可能会有差异,但是原理是相通的。 下面就来看一下 javascript 和 java 中是如何进行处理的?
javascript 获取分组内容
var str = "abcd324232efg";
var reg = new RegExp("([a-z]*)(\\d*)([a-z]*)");
var arr = str.match(reg);
// 显示匹配到的分组内容
alert(arr[0] + "===" + arr[1] + "===" + arr[2] + "===" + arr[3]);
alert(RegExp.$1 + "-----" + RegExp.$2 + "----" + RegExp.$3);
上面的例子中,我添加了 3 个分组。
通过 arr[n]
和 RegExp.$n
的方式都能获取到分组匹配内容。
在 javascript 中
\d
需要进行转义
java 获取分组内容
public static void main(String[] args) {
String str = "abcd324232efg";
Pattern pattern = Pattern.compile("([a-z]*)(\\d*)([a-z]*)");
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
System.out.println(matcher.group());
System.out.println(matcher.group(0));
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
System.out.println(matcher.group(3));
}
}
在 java 中,通过 Matcher.group(n)
的方式拿到分组匹配内容。
在 javascript 中
\d
需要进行转义
小结
分组通常有两种使用场景:一是:对一个子表达式进行重复;二是:想要获取到子表达式匹配到的内容。
分组是通过 ()
来表示的,它是通过从左到右计算其开括号来进行编号的。
更加系统的学习正则表达式的知识,请点击视频讲解:
正则表达式从入门到高手: https://edu.51cto.com/sd/59587
阅读更多文章,请关注公众号: 老王学源码