本文主要是介绍Linux中的正则表达式
适用于需要学习正则表达式的同学。
正则表达式是一种符号表示法,用来识别文本模式,与之前使用过的路径通配符有些相似,但是功能更强大。
需要注意的是,很多系统和编程语言的都是具有正则表达式这个规则的,但是并不完全相同,此处仅学习Linux系统下POSIX标准中藐视的正则表达式,之后其他系统触类旁通学习即可。
grep
主要使用的是grep程序,名字来自于“global regular expression print”,能够在文本文件中查找一个指定的正则表达式,并将匹配到的结果进行输出。
例如先使用ls标准输出/usr/bin的目录名,再通过管道,grep从管道中接受输入,并将匹配结果进行输出。
1 | ls /usr/bin | grep zip |
不通过管道的表达式如下所示:
1 | grep [options] regex [file...] |
选项options有下列情况:
选项 | 描述 |
---|---|
-i | 忽略大小写 |
-v | 获得不匹配项 |
-c | 获得匹配的数量 |
-l/-L | 打印存在匹配/不匹配项的文件夹名 |
-n | 打印匹配项的行号和结果 |
元字符和原义字符
上面grep后的zip
,其中的“z”,“i”,“p”都是按照原本的意思和顺序进行匹配的,这些称为原义字符,需要使用其他规则进行匹配的时候,还包含如下元字符:
1 | ^ $ . [ ] { } - ? * + ( ) | \ |
其中POSIX 规范的字符集又将元字符又存在两种情况,基本正则表达式(BRE)和扩展的正则表达式(ERE),BRE中支持的是^ $ . [ ] *
,ERE在此基础上扩展了( ) { } ? + |
,使用的时候需要增加-E
选项表示执行ERE标准。
元字符 | 解释 | 作用 |
---|---|---|
. | 任何字符 | 可以用来匹配在某个位置的任意一个字符。 |
^ / $ | 锚点 | 该表达式在文本开头/末尾存在才会被匹配。“^$”组合可以匹配空行。 |
[ ] | 指定字符集 | 从中括号内的指定字符集匹配一个字符。元字符在被放置到中括号中后将会失去本身的特殊含义,除了“^”和“-”。 |
^ | 否定 | 在中括号内第一个字符时表示否定,匹配中括号内字符集以外的字符。 |
- | 字符范围 | 例如[a-z],[B-Y],[4-9a-h]等。 |
| | 交替 | 允许从一系列表达式之间选择匹配项。 |
? | 匹配零个或一个元素。 | |
* | 匹配零个或多个元素。 | |
+ | 匹配一个或多个元素。 | |
{ } | 匹配特定个数的元素,n:元素只出现n次,n,m:元素出现[n,m]次,n,:元素出现不少于n次,,m:元素出现不多于m次。 |
补充一些字符集:[:word:]=[:alnum:]+[_];[:alnum:]=[:alpha:]+[:digit:];[:blank:]=空格+tab;[:cntrl:]=0-31和127字符;[:lower:];[:upper:];[:punct:]=标点符号;[:print:]=[:graph:]+[:space:];[:xdigit:]=[0-9A-Fa-f]
其他的基本都可以被视为原义字符。元字符也可以被反斜杠转义为原义字符。
所以之前在shell执行的时候,存在的一些元字符等特殊符号会被展开,这时候就可以使用引号阻止其展开。
应用正则表达式
使用grep匹配
首先使用下列语句生成一个测试的搜索匹配列表,多尝试几次,生成不符合“(nnn) nnn-nnnn”格式的电话号码,以便用来匹配。
1 | for i in {1..10}; do echo "(${RANDOM:0:3}) ${RANDOM:0:3}-${RANDOM:0:4}" >>phonelist.txt; done |
再使用cat和管道连接grep,因为使用了扩展的正则表达式,所以需要使用-E选项:
1 | cat phonelist.txt | grep -Ev '^\([0-9]{3}\) [0-9]{3}-[0-9]{4}' |
使用find查找
查找某个路径下的文件名是否符合满足正则表达式要求,例如查找当前路径下包含空格等不符合规范的路径名。
1 | find . -regex '.*[^-\_./0-9a-zA-Z].*' |
利用locate查找文件
locate支持基本的(--regexp)和扩展的(regex)正则表达式。例如搜索包含指定字符串的路径名。
1 | locate --regex 'bin/(bz|gz|zip)' |
在less/vim中使用正则表达式
less是使用“/
”命令输入正则表达式进行匹配
1 | less phonelist.txt |
vim也类似,不过vim中使用扩展表达式会被认作为文本字符,需要使用反斜杠进行转义为元字符。
1 | /([0-9]\{3\}) [0-9]\{3\}-[0-9]\{4\} |
默认是没有高亮显示的,想要高亮显示的话可以在命令模式下输入:set hlsearch
转化为高亮模式。
个人收获
本章主要学习的是正则表达式,了解到不同系统和语言会具有不完全相同的正则表达式,主要是用于之后的查找和筛选,以及在处理数据的时候能够利用规则直接提取相关信息,比较重要。