正则表达式:正则表达式(regular expression,RE)是一类由特殊字符组合起来的一种字符模式,用于在查找过程中匹配特定的字符。

元字符:元字符是这样的一类字符,它们不表示字符本身的含义,而用于额外功能性的描述意义。

GNU/linux 下常见两种元字符,一种是shell元字符,一种是正则表达式元字符,它们各司其职,shell元字符由linux shell程序来解析,正则表达式元字符则由执行此匹配模式的程序来解析,比如vim、grep、awk等。

shell元字符

匹配任意字符串,例:# ls /etc/p*  列出目录/etc/下以p开头的任意文件

匹配任意单个字符,例:# ls /etc/p? 列出目录/etc/下以p开头,后跟只有一个字符的文件

[] 匹配括号中的任意一个字符,例:[.,;] 匹配点号或逗号或分号

[-] 匹配括号中一个范围内的任意一个字符,例:[a-z] 匹配任意一个小写字母

[!] 匹配括号字符之外的任意一个字符,例:[!abc] 匹配字符a、b、c之外的任意一个字符

基本正则表达式元字符

常用元字符(matecharacter):

^:脱字符,锚定行首的符合条件的内容,用法^pattern

$:锚定行尾的符合条件的内容,用法pattern$

^$:匹配空白行

^pattern$:精确匹配pattern

. :点号,匹配任意单个字符

* :匹配紧挨在其前面的字符任意次,有数量的概念

.* :匹配任意长度的任意字符(不包含换行符),此匹配是工作在贪婪模式下,尽可能 长的去匹配符合条件 的内容

[]:匹配指定范围内的任意单个字符

[^]:匹配指定范围外的任意单个字符

\{m,n\}:匹配其前面的字符至少m次,至多n次

\{0,n\}:匹配其前面的字符至多n次

\{m,\}:匹配其前面的字符至少m次

\< :锚定词首

\> :锚定词尾


扩展正则表达式元字符

基本正则表达式里的元字符在扩展正则里也同样适用,只是增加了以下一些元字符。

增加的元字符:

+:匹配其前面的字符至少1次

?:匹配其紧挨着前面的字符0次或1次

x{m}:字符x重复m次

x{m,}:字符x重复至少m次

x{m,n}:字符x重复m-n次

():分组,支持引用

|:表示或者


方括号类字符

[:alpha:]   所有字母字符,包括大小写

[:upper:]  所有大写字母字符

[:lower:]   所有小写字母字符

[:digit:]     所有数字字符

[:alnum:]  所有数字与字母字符

[:space:]  所有空白字符,包括空格、换行符、制表符

[:punct:]   所有标点字符

[:graph:]  所有非空白字符,不包含空格、控制字符

[:print:]    [a:graph:]类似,但包含空格字符

[:cntrl:]     控制字符

[:xdigit:]   十六进制数字字符


小结:扩展的正则表达式也可以在基本正则表达式中使用,只要在元字符前加上“\”转义符即可,如“\+”“\|”等。正则表达式也只是一种特殊的模式匹配而已,它要想工作起来也必须要利用一些工具才行,比如:vim、grep、sed、awk等。


常用正则使用举例:

以下的例子都是从网上转载,只是对这些正则表达式进一步进行了分析,来源:http://deerchao.net/tutorials/regex/common.htm

1、匹配一个网址(URL)

表达式:[a-zA-Z]+://[^\s]*

分析:“[]”表示匹配方括号内的任何字符;[a-zA-Z]表示匹配26个英文字母中的任何一个,且不分大小写;“+”号表示前一个元素可出现1次或多次,所以“[a-zA-Z]+”表示方括号中的字符可以出现1次或多次,这部份在URL中表示是协议部份;“://”是URL中的固定格式;“[^\s]*”表示匹配非空白字符任意次,包含零次。

实例:

[root@zcj test]# cat jj.txt
HTTP://www.baidu.com
http://www.BAIDU.com
http://www.baidu.com
https://www.baidu.com
thx://www.baidu.com

正则表达式_功能性

正则表达式_表达式_02

2、匹配IP地址

表达式:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)

分析:IPV4地址是由四个点号分隔成的四个十进制位,称为点分十进制,每一组的取值范围是0-255(包括网络地址和广播地址),那么这个范围要分成几种情况才能匹配完,把0-255这个范围分成0-199、200-249、250-255三组,“[01]?\d\d?”正好匹配0-199,“2[0-4]\d”正好匹配200-249,“25[0-5]”匹配250-255;能把这一部份理解清楚,那上边的匹配IP地址的表达式也就能理解了。

实例:

正则表达式_功能性_03

不知道什么原因,系统里的egrep不能识别“\d”这个模式,只好换成“[0-9]”,效果也是一样的。

3、匹配Email地址

表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

分析:这个表达式写得比较复杂,把不常见的格式也匹配了,比如会把“sky+33@163.com-cn”这样的邮件地址也会匹配到,而我们常见的邮件地址会是“sky@sina.com.cn”“sky12@163.com”“sky_23@126.cn”“12345@sina.com”这样类似的例子。先来拆分上边表达式中各部份的意义:“\w”这个非常有意思,它表示任何单词字符匹配(我的理解就是一个单个字符),但不会匹配到“+”“-”“.”等字符,但会匹配到“_”,并且匹配到的是单个单词字符,所以“\w+”会匹配到多个单个字符组成的字符串;“([-+.]\w+)*”表示在三个特殊符号后边跟上了任何单词字符,后边整体跟上了一个“*”号,表示这样的模式可以出现任何次数,包括零次,这样就比较符合在邮件地址格式中@符号的前部份了;“([-.]\w+)*\.\w+([-.]\w+)*”后边的这个表达式分成了两部份,且都是用“*”号来进行对前边的小括号内的匹配模式进行次数匹配,这样模式就写得非常有灵活性,可以匹配到类似“@163.com”的,也可以匹配到“@163.com.cn”的,不得不佩服正则表达式的强大。

实例:

[root@zcj test]# cat mail.txt
sky_551@163-com
sky@126.com.cn
sky.551@sina.com-cn
sky+551@sina.com
sky-551@sina.com
sky_22@sina
sky5511@yaho.cn
d   3  )  _  ~
2222@13.com

正则表达式_换行符_04

4、匹配qq号码

表达式:[1-9]\d{4,}

分析:[1-9]表示1-9这9个数字中的任何一个,“\d”表示匹配“0-9”间的任何一个数字,相当于[0-9]这个模式,{4,}这个表示其前边的字符至少出现4次。那这个表达款就能匹配到长度是大于等于5的qq号码。

实例:正则表达式_表达式_05

5、匹配“年-月-日”

表达式:(\d{4}|\d{2})-((1[0-2])|(0?[1-9]))-(([12][0-9])|(3[01])|(0?[1-9]))

分析:(\d{4}|\d{2})表示年可以是4位的年,也可以是2位的年;((1[0-2])|(0?[1-9]))表示把月分成两种可能,一种是1到9月这种一位的年,也可写成“01-09”这种月的格式,另一种是10月至12月,这种两位的月;(([12][0-9])|(3[01])|(0?[1-9]))表示把日分成了三种可能,因为一个月最长有31天,把31天分成以下几种可能,一是1-9号,二是10-29号,三是30-31号。“0?[1-9]”表示1-9号(也可01-09),“[12][0-9]”表示10-29号,“3[01]”表示30-31号。

实例:

正则表达式_表达式_06