由于元字符.默认无法匹配换行符,所以需要匹配换行符的时候,可以使用特殊组合[\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