linux 正则表达式详解

2020-08-20 21:36:07 浏览数 (1)

声明

以下内容均总结自鸟哥私房菜这本书,如想详细了解,请参考该书以及其它相关资料。学习下面基础正则表达式之前请先简单了解一下grep的用法。

基础正则表达式

基础正则表达式语法

RE字符

含义

^word

待搜寻的字符串(word)在行首!

word$

待搜寻的字符串(word)在行尾!

.

代表『任意一个』字符,一定是一个任意字符!

转义字符,将特殊符号的特殊意义去除

*

代表『任意一个』字符,一定是一个任意字符!

[list]

找出包含在list集合里面的字符

[n1-n2]

找出包含在n1-n2范围内的字符,这个是[list]的一种特殊写法,要求n1-n2使有序的,比如a-z表示小写字母,A-Z表示大写字母,0-9表示数字0到9,连续与否与ASCII哟有关

{n,m}

这是限定连续RE字符的范围,{n,m}表示连续前一个字符的个数在n到m之间,若为{n}则表示连续n个前一个字符,若为{n,}则表示连续n个以上前一个字符

[^list]

匹配不在list集合里面的字符

仅看上面的规则可能不能完全看懂,下面结合实际的例子来讲解,在讲解之前请先执行下面指令将文本样例下载下来。

代码语言:javascript复制
wget http://linux.vbird.org/linux_basic/0330regularex/regular_express.txt

样例详解

1.查找特定字符串

查找包含the的行

代码语言:javascript复制
[root@localhost tmp]# grep -n 'the' regular_express.txt

查找不包含the的行

代码语言:javascript复制
[root@localhost tmp]# grep -nv 'the' regular_express.txt

不区分大小写

代码语言:javascript复制
[root@localhost tmp]# grep -in 'the' regular_express.txt

查找包含Tast或者test字符串的行

2.使用[list]规则来进行查找

查找包含taste或test字符串的行

代码语言:javascript复制
[root@localhost tmp]# grep -n 't[ae]st' regular_express.txt

注意这里面正则表达式t[ae]st只能表示两个值tast或test,不能表示taest,也就是[]里面的字符串只选一个进行结合。

查找包含oo的行

代码语言:javascript复制
[root@localhost tmp]# grep -n 'oo' regular_express.txt 

查找oo前面的字符不是g的行

代码语言:javascript复制
[root@localhost tmp]# grep -n '[^g]oo' regular_express.txt

查找oo前面不是小写字母开始的行

代码语言:javascript复制
[root@localhost tmp]# grep -n '[^a-z]oo' regular_express.txt

这里面的-符号是有特使含义的,表示连续一组字符,字符是否连续和ASCII有关,这是一种简写,你也可以在[]里把a到z的所有字符全部写出来,明显没有[a-z]简单。同样的[0-9],[A-Z]也是简写。

3.对行首和行尾字符进行限定^$

行首以字符串the开头

代码语言:javascript复制
[root@localhost tmp]# grep -n '^the' regular_express.txt

行首以小写字母开头

代码语言:javascript复制
[root@localhost tmp]# grep -n '^[a-z]' regular_express.txt

行首不是英文字母开头

代码语言:javascript复制
[root@localhost tmp]# grep -n '^[^a-zA-Z]' regular_express.txt
1:"Open Source" is a good mechanism to develop programs.
21:# I am VBird

这里要注意了,^这个符号在[]里面和外面是完全不一样的,在外面表示定位在行首,起到定位的作用,在里面表示非的意思。

查找以.结尾的行

代码语言:javascript复制
[root@localhost tmp]# grep -n '.$' regular_express.txt

使用$定位在行尾,想要以.结尾的,但是.有特殊意义,所以需要使用来转义吗, 来解除其特殊含义。在linux中每行是以$来结尾的,那么如何匹配空白行呢?

代码语言:javascript复制
[root@localhost tmp]# grep -n '^$' regular_express.txt 
22:

所以如果想过滤文件中空白行和注释行,可以使用下面的指令

代码语言:javascript复制
[root@localhost tmp]# grep -v '^$' /etc/sysconfig/iptables-config | grep -v '^#'

grep -v ‘^$’表示过滤空白行,grep -v ‘^#’表示过滤注释行。

4.任意一个字符.与重复字符*

. 代表一定有一个任意字符 * 代表重复前一个0到无穷多次的意思 找出g??d的字符,即g开头,d结尾的四个字符

代码语言:javascript复制
[root@localhost tmp]# grep -n 'g..d' regular_express.txt 

如果想要列出含有oo,ooo,oooo等的数据,也就是至少含有两个o以上。用o*合适吗?不合适。因为表示前面字符重复0到任意多次,所以可以是空,啥都没有,所以o会匹配出所有数据。应该使用oo*,即至少有一个o,同理至少两个o为oo*。

代码语言:javascript复制
[root@localhost tmp]# grep -n 'oo*' regular_express.txt

匹配字符开头和结尾都是g,中间必须是o且可以有多个,即gog,goog,gooog等

代码语言:javascript复制
[root@localhost tmp]# grep -n 'goo*g' regular_express.txt

找到g开头和g结尾的

代码语言:javascript复制
[root@localhost tmp]# grep -n 'g.*g' regular_express.txt

包含任意数字

代码语言:javascript复制
[root@localhost tmp]# grep -n '[0-9][0-9]*' regular_express.txt
5.限定连续字符范围{}

由于{}在shell中是有特殊含义的,所以使用时需要先转义 限定字符中只包含两个o

代码语言:javascript复制
[root@localhost tmp]# grep -n 'o{2}' regular_express.txt

gg中间包含2到5个o

代码语言:javascript复制
[root@localhost tmp]# grep -n 'o{2,5}' regular_express.txt

gg中间至少包含两个o,这个又两种写法

代码语言:javascript复制
[root@localhost tmp]# grep -n 'gooo*g' regular_express.txt
[root@localhost tmp]# grep -n 'go{2,}g' regular_express.txt

注意:”!”在正则表达式中并不是特殊字符,所以要想查找文件中含有!和>字符的行,可以这样。

代码语言:javascript复制
[root@localhost tmp]# grep -n '[!>]' regular_express.txt

强调一下,正则表达式和linux的通配符是不一样的,在通配符中*代表零到无限多个字符,比如我使用

代码语言:javascript复制
[root@localhost tmp]# ls test*
test.patch

拓展正则表达式

了解基础正则表达式已经足够了,但是有些时候为了简化操作,也需要使用扩展正则表达式。比如使用基础正则表达式去除空白行和行首是#开头的注释行,使用

代码语言:javascript复制
[root@localhost tmp]# grep -v '^$' regular_express.txt | grep -v '^#'

如果使用扩展正则表达式可以使用

代码语言:javascript复制
[root@localhost tmp]# egrep -v '^$|^#' regular_express.txt

使用扩展表达式时,使用egrep而不是grep。

扩展正则表达式语法

RE字符

含义

重复一个或一个以上的前一个RE字符

零个或者一个前一个RE字符

|

表示或

()

查找组字符串

()

多个重复组判断

样例详解

1. :重复一个或一个以上的前一个RE字符

找出包含god,good,goood的行

代码语言:javascript复制
[root@localhost tmp]# egrep -n 'go d' regular_express.txt
1:"Open Source" is a good mechanism to develop programs.
9:Oh! The soup taste good.
13:Oh!  My god!
2. ?:零个或者一个前一个RE字符

找出包含gd或god的行

代码语言:javascript复制
[root@localhost tmp]# egrep -n 'go?d' regular_express.txt
13:Oh!  My god!
14:The gd software is a library for drafting programs.
3. |:或

找出包含god,good,或者dog的行

代码语言:javascript复制
[root@localhost tmp]# egrep 'god|good|dog' regular_express.txt
"Open Source" is a good mechanism to develop programs.
Oh! The soup taste good.
Oh! My god!
I like dog.
4. ():查找组

找出包含glad或者good的行

代码语言:javascript复制
[root@localhost tmp]# egrep 'g(oo|la)d' regular_express.txt
"Open Source" is a good mechanism to develop programs.
Oh! The soup taste good.
The world <Happy> is the same with "glad".
5. () :多个重复组判断

在下面的文本内容中,找出以A开头C结尾的含有一个以上的xyz字符串。 文本内容: 1.sasbAxyzxyzxyzCqwee 2.sdafAxysaC

代码语言:javascript复制
[root@localhost tmp]# echo '1.sasbAxyzxyzxyzCqwee
2.sdafAxysaC' | egrep 'A(xyz) C'
1.sasbAxyzxyzxyzCqwee

强调

ls test*表示查找文件名test开头的文件。而在正则表达式中*则代表重复前面的RE字符0到无穷多次,通配符和正则不要搞混了。

0 人点赞