2013年07月29日

正则表达式


基本

正则表达式真是强大,前前后后看了很多次,但是由于使用的不够频繁,很容易并忘记了。并且,在使用vi,sed等linux 工具或者命令时,发现不同的工具直接正则表达式差别还挺大,正常习惯写的表达式可能无法识别。今天特意翻阅资料并将其记录下来,下次能有一个自己能迅速看懂唤起记忆的博文。

同一个正则表达式在不同工具之间还不一样,有的能识别,有的不能识别,有的需要转义字符,有的又不需要,这是因为正则表达式有多个派别,可以参考这里

正则表达式的文法分为三种标准:BRE,ERE和ARE, 前两者属于POSIX标准,后者则是由各家自定义扩展。

POSIX规范定义来BRE(Basic Regular Expression,基本正则表达式)和ERE(Extend Regular Expression,扩展正则表达式),在兼容POSIX的UNIX系统上,grep和egrep之类的工具都遵循POSIX规范。

在Linux常用工具中,例如grep vi sed 都是遵循于BRE这一派系,元字符{, },(, )必须要经过转义之后才有特殊含义,例如表达式a{1,2}只能匹配“a{1,2}”而不能匹配a或aa,如果改为a\{1,2\},这样就可以匹配a或者aa了。不过纯粹的BRE已经很少见了,虽然VI属于BRE流派,但提供了其他的基本功能,GNU也对BRE做了扩展,以支持+ ? |,只是使用时必须写成\+ \? \|,而且也支持反向引用。

在Linux常用工具中,例如egrep,awk等属于ERE流派,这样的情况下,元字符不需要转义了。在上面的博文中截取了两张图片,更加清晰的描述了不同工具使用正则表达式之间的一些差别。

基本正则表达式

POSIX的标准之一BRE,即基本正则表达式。参考文章, 其中,BRE定义的语法符号包括:

*     匹配前面的子表达式0次或者多次。例如 "a*" 可以匹配a,aa,还可以匹配b(表示a出现0次)

.      匹配任意一个字符,不能匹配换行符\n

[]     字符集匹配,匹配括号中定义的字符集之一,例如[0-9],匹配0到9的任意数字

^      匹配开始配置

$      匹配结束位置

\(\)   定义子表达式,例如\(a{2}\)\1,后面的\1就引用此子表达式aa,等价于匹配aaaa

\n     子表达式向前引用,n为1到9之间的数字

\{m,n\} 匹配前面的子表式至少m次,至多n次,贪婪的去匹配,例如有字符串aaaa,a{2,3},则匹配结果是前面的三个a

扩展正则表达式

ERE修改了BRE中的部分与阿发,并增加了以下语法符号:

?      匹配前面的子表达式零次或者一次

+      匹配前面的子表达式一次或者更多次

|      或运算,匹配左表达式或者又表达式

下面还有一些元字符,

\<     匹配单词的开头 

\>\     匹配单词的结尾

[^]    匹配不在括号内的任意字符

()     这样构成一个独立的子表达式

常见例子

匹配IP地址: (([0-9] | [1-9][0-9] | 1[0-9]{2} | 2[0-4][0-9] | 25[0-5])\.){3}([0-9] | [1-9][0-9] | 1[0-9]{2} | 2[0-4][0-9] | 25[0-5])

匹配EMAIL: EMAIL的匹配不是一个简单的事,若要匹配全部RFC指定的email地址很复杂,对于一般情况,可以这样: ^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+

IP参考链接, EMAIL参考链接

前一篇: Openstack Api分析(一) 后一篇: Openstack Paste Deploy介绍