0
点赞
收藏
分享

微信扫一扫

19-正则表达式

邯唐情感 2022-02-06 阅读 41

grep

用来处理正则表达式的主要命令是grep,grep的基本功能是在文本文件中搜索与指定的正则表达式匹配的文本,将其输出至标准输出

grep [options] regex [file...]
常用选项描述
-i忽略大小写
-v反向匹配,即输出和正则表达式不匹配
-c输出匹配数量
-l输出包含匹配项的文件名
-L输出不包含匹配项的文件名
-n在输出的文本行之前加上行号
-h在多文件搜索中禁止输出文件名
-Egrep -E <=> egrep,即适用ERE扩展型正则表达式的grep

当我们只对包含指定字符串的文件感兴趣,那么-l选项是非常有用的;
如果我们对不包含指定字符串的文件感兴趣,-vl可以实现这一功能;
多文件搜索会在匹配的文本行之前加上它所属的文件名,如果对文件不感兴趣,可以使用-h选项

注意-E选项,

元字符和文本字符

所谓的元字符是指表示特定含义的字符,区别于文本字符,正则表达式分为 基本型正则表达式BRE扩展性正则表达式ERE,它们的不同之处在于:识别的元字符是不同的

注意:

  1. 很多元字符对于shell本身也是有意义的,比如*在shell中就可以扩展成任意长度的字符,所以,当正则表达式出现在命令行的时候,一定要将其放入引号中

  2. 反斜线\,可以用来创建元序列,也可以用来转义成文本字符,听起来很矛盾,但是看使用场景

任意字符.

元字符点号".",它用来匹配任意一个字符

锚点^和$

脱字符^和美元符号$ 被视为锚点,分别代表行首和行尾

# ^和$称为锚点非常合适,因为它们就是单纯地表示位置
grep -h '^zip$' dirlist*.txt

特别的:’^$’ 表示空行

多选结构 |

正则表达式 ‘AAA|BBB’ 的意思是要么匹配 ‘AAA’ 要么匹配 ‘BBB’,多选结构 ‘|’ 是ERE的特性之一

注意:

  1. 适用多选结构的时候,记得正则表达式加上引号,前文也说过,很多元字符在shell中也具有特殊意义,比如 ‘|’ 在shell中意味着管道,为了防止shell的展开规则对正则表达式的影响,如果在命令行上书写正则表达式,需要加上引号

量词

ERE扩展型正则表达式支持指定匹配次数

? 匹配零次或一次

该量词表示:之前的元素是可选的,可以有,也可以没有,或者说出现零次或一次

注意:

  1. 是紧邻着’?'的前一个字符,如果你想表示一块都是可选的,可以使用圆括号把它们括起来,组成一部分。

* 匹配零次或多次

类似于 ‘?’ 区别在于,*能够匹配多次

+ 匹配一次或多次

类似于 ‘?’ 或 ‘*’ ,区别在于匹配的次数

示例:

# 匹配由大写字母开头,其之后不管有几个大写字母或小写字母或空格都能匹配,最后以'.'结尾
'^[[:upper:]][[:upper:][:lower:] ]*\.$'

# 开头就是一个或多个字母,其后可能有空格,这样的组合重复一次或多次
'([[:alpha:]]+ ?)+'

{} 指定匹配的次数

共有四种指定的方式

指定方式含义
{n}匹配n次
{n,m}至少匹配n次,至多m次
{n,}至少匹配n次,无上限
{,m}至少匹配0次,至多m次

方括号和字符类

可以使用方括号来匹配指定范围字符中的单个字符

# 匹配含有bzip或者gzip的行
grep -h '[bg]zip' dirlist*.txt

排除

如果方括号中的首个字符是脱字符^,相当于取反匹配,即匹配不含有脱字符后面字符的行

注意:

  1. 只有当脱字符^作为方括号表达式中的第一个字符的时候,才表示排除含义;否则它只是一个普通的字符

字符范围

方括号还可以使用连字符,表示一段范围的字符,比如[a-zA-Z]表示小写字母和大写字母,[0-3]表示数字0、1、2、3

POSIX字符类

POSIX是IEEE制定的一套规范UNIX工作方式的标准,包括程序的接口、shell以及标准类UNIX系统中的实用工具

ASCII码表中,大写字母+小写字母顺序排列的

ABC...Zabc...z

正常的词典序列是,大小写间隔排列的

aAbBcC...zZ

POSIX引入了语言环境的概念,能够调整特定区域所需要的字符集,查看系统的语言设置echo $LANG,总之,正因为如此,后来兼容POSIX的应用会使用词典序列,这样,显然[a-z]或者[A-Z]就不再具有通用性

因此,建议在匹配字符范围的时候,尽可能使用POSIX的字符类

常用的字符类描述
[:alnum:]字母和数字 <=> [a-zA-Z0-9]
[:word:]在[:alnum:]的基础上增加了下划线_
[:alpha:]字母 <=> [a-zA-Z]
[:digit:]数字0-9
[:lower:]小写字母
[:upper:]大写字母
[:space:]空白字符

ps:相信你还记得,POSIX类同样适用于和通配符搭配,用于shell扩展

应用示例

grep -Ev '^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$' phonelist.txt

分析:第一段 ^\([0-9]{3}\) 表示开头就是一个括号,里面三个数字,使用转义字符是将圆括号转义成普通字符;第二段 [0-9]{3}-[0-9]{4}$表示三个数字和四个数字,中间是连字符连接,至此结尾;grep -Ev则是表示使用ERE扩展型正则表达式,v则是表示不符合正则表达式规则的文本行将被找出来

find . -regex '.*[^-_./0-9a-zA-Z]'

分析:find选项 -regex,即使用ERE扩展型正则表达式,.*表示匹配零个或多个字符,方括号以开头,则表示排除以后的字符;整体则表达找出不含-_./0-9a-zA-Z的路径

locate --regex `bin/(bz|gz|zip)`

分析:–regex表示采用ERE扩展型正则表达式,看点主要是后面利用多选结构,匹配含有bz 或 gz 或 zip的文件名

注意:如果是多选结构,最后一开始就加上括号,表示多选结构是一块的,要不然可能会有纰漏,比如^(bz|gz|zip)^bz|gz|zip表达的是不一样的,前者表示可能是bz开头或者gz或zip,后者则一定是bz开头其后或者是gz或者是zip

less或者vim均支持正则表达式查找,输入/或者?就能够查找,但是vim只支持BER基本型正则表达式,很多ERE中支持的元字符,在BER中就是普通字符,这个时候需要利用转义字符,将普通字符转义成元字符

举报

相关推荐

0 条评论