POSIX正则表达式 | BRE和ERE
简介
POSIX标准定义了两种regex,分别是BRE(Basic Regular Expression)和ERE(Extended Regular Expression)。linux中的命令(程序)如grep,less,以及一些数据库都实现了POSIX正则表达式。
现代大多数IDE或编程语言使用的正则匹配表达式都更加类似于ERE,而且相比ERE在功能上做了更多的拓展。本文介绍拓展后的BRE,ERE在表达上的差别,对功能的差别不做区分。
基础语法
括号表达式
POSIX括号表达式形如[...]
,能够匹配表达式所表达的字符集中的一个字符,称为character class。
和一般character class类似,使用[^
来反选字符集,使用-
来表达范围。
POSIX未定义\d
, \w
等缩写,但支持以下的命名类:
Character Group | Meaning |
---|---|
[:alnum:] | Alphanumeric:字母和数字 |
[:cntrl:] | Control Character:控制字符,如DEL,BS等 |
[:lower:] | Lower case character: 小写字母 |
[:space:] | Whitespace:空白字符,包括tab,vertical tab,line feed,carrige return等 |
[:alpha:] | Alphabetic:字母 |
[:digit:] | Digit:数字 |
[:print:] | Printable character:可打印的字符,包括[:alnum:], [:space:], [:punct:]。 |
[:upper:] | Upper Case Character:大写字母 |
[:blank:] | 一般是空格和tab |
[:graph:] | Printable and visible characters:[:print:] 去掉空白类 |
[:punct:] | Punctuation:标点符号 |
[:xdigit:] | Extended Digit:数字再加上A, B, ..., F. |
使用命名类时,需要它们放入括号表达式,例如,[[:digit:]]+
才能表示连续多个数字,[:digit:]+
是错误的表达。又如,[[:alpha:][:digit:]]
等同于 [[:alnum:]]
。
特殊字符
又称作Metacharacter:就是指正则表达式中如+
(出现一次或多次), |
(或)等有特殊意义的字符。
\w
等效于 [[:alnum:]_]
表示匹配次数的一些表达:
*
匹配任意次数,?
匹配一次或0次,+
匹配一次或多次{n}
:恰出现n次{n,}
出现n次或更多{,m}
:最多m次。这是GNU拓展。{n,m}
:最少n次,最多m次
使用 (
, )
来捕获组。
使用 \<
和 \>
分别匹配词首和词尾。使用 \b
匹配词首,等效于 \<
。
使用 ^
表示行首,$
表示行尾。
POSIX BRE vs ERE
grep,sed,vim默认使用BRE语法匹配。
grep,sed加上 -E 选项能够使用ERE匹配。
vim搜索时使用 \V
来设置no magic,搜索字面值;使用 \V
来设置very magic。替换使用 sno 来no magic匹配。
BRE,ERE原本是有功能上的区别的,例如BRE不支持+
。但是目前在GNU工具的实现中,二者功能基本一致。唯一的区别在于很多特殊字符在BRE中需要前加 \
才能表示特殊意义。
例如, "a+" 在BRE中不能够匹配 "a", "aa", ... 而只匹配 "a+"。在ERE中它能够匹配 "a", "aa", ...
这里简单列出一些在BRE中需要带反斜杠的特殊字符:\+
, \?
, \(
, \)
, \{
, \}
。值得注意,*
, .
在两种语法中都不需要加反斜杠表示特殊含义,而 \<
和 \>
在两种语法中都需要加上反斜杠。
其他
二者均支持capturing group和backreference。使用\n
即可表示backreference,其中n是索引,但对于BRE,n取值在1至9之间。
此外,POSIX正则总是greedy,不支持其他的模式。
对于word边界的匹配,POSIX定义了[[:<:]]
和[[:>:]]
分别表示匹配左边界和右边界。经过测试,vim和less都不支持POSIX的定义,但支持\<
, \>
。
一些示例
具体用例可以参考grep和sed中的实用例子。