特殊且常用的的组合正则表达式:
需要解释清楚的是这些量词(也就是上面匹配的次数元字符)的特殊性:当使用了匹配多次的量词时(如匹配3-5次的{3,5}
),且量词前面的字符有多种可能性(如中括号序列[abc]
),那么量词的次数可以作用于任一字符。有些不好理解,但看示例就知道了:
另外,.
无法匹配换行符。可能你不太理解为什么需要匹配换行符,它主要用在:
中括号表示的是匹配任意一个,一般它和字符集的排序规则有关,不同工具采取的排序规则可能也不一样。
关于字母的排序:
是专门命名的中括号序列;除了字符类,还有等价类、排序类,但基本用不上,只用字符类。
需要注意的是,通常字符类在真正使用过程中,会再加上一个中括号,例如[[:alpha:]]
。之所以如此,是因为这些字符类只是一种命名好的字符集合。例如[:lower:]
对应的字符集合是a-z,而不是[a-z]
,所以要想让其表示这些命名字符类中的任一字符,需要再加上一层括号[[:lower:]]
,它才等价于[a-z]
。可能会更有助于理解使用字符类的时候为什么要加两个中括号的例子是[^[:lower:]]
,它表示不包含任何小写字母。
不同的工具,同一工具不同的版本,支持的反斜线序列能力不同。以下列出了部分常见序列。
以下所说的单词,一般来说只包含数字、字母和下划线,即[_0-9a-zA-Z]
。
以下几种反斜线序列,基本上所有工具都支持:
以下几种,有些工具不支持,但perl都支持:
由于元字符.
默认无法匹配换行符,所以需要匹配换行符的时候,可以使用特殊组合[\d\D]
来替换.
,换句话说,如果想匹配任意长度的任意字符,可以换成[\d\D]*
,当然,前提是必须支持\d
和\D
两个反斜线序列。
基础正则中,使用括号可以对匹配内容进行分组并暂时保存,分组后会有分组编号,可以使用反斜线加编号\N
的方式反向引用这些分组。
分组编号的方式是从左向右计算括号数,无论如何嵌套,第一个左括号对应的分组一定是编号1,用\1
来引用,第二个左括号对应的分组一定是编号2,用\2
来引用,依此类推。
例如grep的分组捕获:匹配两个连续相同的字母。
可以认为分组就是变量赋值的过程。例如,上面示例的匹配过程如下:
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个的分组,使用基础正则的工具一般来说是无能为力的。
关于二选一的结构,几点需要说明:
在二选一结构种,两个反向引用问题的典型例子:
例如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,因为第一个分组括号在左边,无法参与右边的正则评估。