基础正则表达式详述(2)

由于元字符.默认无法匹配换行符,所以需要匹配换行符的时候,可以使用特殊组合[\d\D]来替换.,换句话说,如果想匹配任意长度的任意字符,可以换成[\d\D]*,当然,前提是必须支持\d和\D两个反斜线序列。

分组捕获和反向引用

基础正则中,使用括号可以对匹配内容进行分组并暂时保存,分组后会有分组编号,可以使用反斜线加编号\N的方式反向引用这些分组。

分组编号的方式是从左向右计算括号数,无论如何嵌套,第一个左括号对应的分组一定是编号1,用\1来引用,第二个左括号对应的分组一定是编号2,用\2来引用,依此类推。

例如grep的分组捕获:匹配两个连续相同的字母。

echo "abcddefg" | grep -E "(.)\1"

可以认为分组就是变量赋值的过程。例如,上面示例的匹配过程如下:
1.匹配第一个字母a,放进分组,即赋值给变量(假设变量名为$1),即$1="a",再继续执行正则表达式匹配过程的反向引用,它引用的是$1,于是表示第一个字母a后面还要是字母a,于是匹配失败。
2.匹配第二个字母b,放进分组,即$1="b",再匹配后一个字母,于是匹配失败。
3.字母c同样如此。
4.匹配字母d,放进分组,即$1="d",再匹配后一个字母,发现匹配成功,于是$1被保存下来。
5.已经匹配成功,于是结束。

对于只使用基础正则的工具来说,一般都只能引用\1到\9共9个反向引用,最多自己额外提供一个所有表示匹配内容的反向引用(例如sed提供的&)。对于超出10个的分组,使用基础正则的工具一般来说是无能为力的。

再者,基础正则仅仅只是将分组匹配到的内容捕获,在正则操作结束后就丢失。但对于一门完整编程语言来说,这远远不够,几乎所有编程语言(如perl/Java/Python等)都会将正则的分组匹配内容保存为变量,使得可以在正则结束之后再次引用甚至修改它们。例如上面例子中分组捕获的字母d,如果换成perl,即使在这个匹配过程结束后,还是可以去引用这段分组。

二选一

pattern1 | pattern2:匹配竖线左边,或者匹配竖线右边都算匹配成功

关于二选一的结构,几点需要说明:

因为竖线元字符的优先级很低,所以ab|cd匹配的是"ab"或"cd",而不是abd或acd。

成功匹配了左边,就不会再去对右边进行匹配。

反向引用失败问题:竖线将两边的分组隔开,右边的永远无法反向引用左边的分组

在二选一结构种,两个反向引用问题的典型例子:

例如a(.)|b\1将无法匹配"ba",因为评估了左边就不会评估右边。

例如([ac])e\1|b([xyz])\2t的左边能匹配aea或cec,但不能匹配cea或aec,右边能匹配bxxt或byyt或bzzt。但如果将\2换成\1,即([ac])e\1|b([xyz])\1t,将无法匹配b[xyz]at或b[xyz]ct,因为第一个分组括号在左边,无法参与右边的正则评估。

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/4103733ab2cf96aab507a94855f4858c.html