shell编程(8) 之正则表达式
正则表达式
- 什么是正则表达式?
正则表达式是一种模式匹配语言,用它来筛选数据以查找特定的内容,不仅 vim、grep、sed 等命令会使用到正则表达式,在 Python 等编程语言以及主流应用如 MySQL 中也会使用到正则表达式。正则表达式是通过正则表达式引擎(regular expression engine)实现的
在 Linux 中,有两种流行的正则表达式引擎:
- POSIX 基础正则表达式(basic regular expression,BRE)引擎
- POSIX 扩展正则表达式(extended regular expression,ERE)引擎
大多数 Linux 工具都至少符合 POSIX BRE 引擎规范,能够识别该规范定义的所有模式符号。但某些工具,比如 sed 编辑器,只符合了 BRE 引擎规范的子集。
纯文本
正则表达式模式都区分大小写,在正则表达式中不用写出整个单词,只要定义的文本出现在数据流中就可以匹配
- 正贼表达式中特殊字符:. * [] ^ $ {} \ + ? | ()
如果要使用上方特殊字符作为文本字符,就必须进行转义操作
grep '\$' 字符
锚字符
指定一个正则表达式模式时,只要模式出现在数据流中的任何地方,它就能匹配
- 行首定位符:^ 必须将他放在正则表达式中指定的模式前面
ps:如果指定正则表达式模式时只用了脱字符,就不需要使用反斜线来转义。但如果在模式中先制定了脱字符,随后还有其他一些文本,那么就必须在脱字符前用转义字符 - 行尾定位符:$
点号字符
用来匹配除了换行符之外的任意单个字符,他必须匹配一个字符,如果在 . 位置上没有字符则该模式不成立
grep ".ello" 文件名
字符组
-
[]
限定匹配具体字符,使用方括号定义一个字符组,方括号中包含你希望出现该字符组中的字符
grep "[ch]at" 文件名 #显示包含cat、hat的行
-
排除型字符组
grep "[^ch]at" 文件名 #寻找匹配除了cat、hat的行
ps:字符组必须匹配一个字符,所以 at 开头的行未能匹配模式
区间
只需要指定第一个和最后一个字符就可以
grep "[0-9][0-9][0-9][0-9][0-9]" 文件名
grep "[a-z]at" 文件名 #只有at无法匹配该模式
星号
放在字符后,该字符必须在匹配模式的文本中出现 0 次或多次
grep '1.*0' 文件名 #找出 1 和 0 之前有任意字符的内容
=======================================
下面是 gawk 程序脚本中的较常见的 ERE 模式符号
问号
说明:问号表明前面的字符可以出现** 0 次或 1 次**,不会匹配多次出现的字符
[biying@localhost]$ echo "bt" | gawk '/b[ae]?t/{print $0}'
bt
[biying@localhost]$ echo "bpt" | gawk '/b[ae]?t/{print $0}'
# 什么输出都没有
加号
星号的另一个模式,加号前面的字符可以出现** 1 次或多次**,至少出现 1 次
[biying@localhost]$ echo "bt" | gawk '/b[ae]+t/{print $0}'
[biying@localhost]$ echo "bat" | gawk '/b[ae]+t/{print $0}'
bat
花括号(为重复的正则表达式指定一个上限,即间隔)
可以使用两种格式来指定区间
- m:正则表达式准确出现 m 次
- m,n:正则表达式至少出现 m 次,至多 n 次
ps:正常情况下,gawk 程序不会识别正则表达式间隔,必须指定 gawk 程序的 --re-interval 才能识别正则表达式间隔
[biying@localhost]$ echo "bet" | gawk --re-interval '/be{1}t/{print $0}'
bet
[biying@localhost]$ echo "bet" | gawk --re-interval '/be{1,2}t/{print $0}'
bet
#通过指定间隔为 1,来限定字符在字符串中出现次数
管道符号(逻辑or)
检查数据时,用逻辑或指定正则表达式引擎要用的两个或多个模式
[biying@localhost]$ echo "the cat is sleep" | gawk '/cat|dog/{print $0}'
the cat is sleep
[biying@localhost]$ echo "the sheep is sleep" | gawk '/cat|dog/{print $0}'
#正则表达式与管道符号之间不能有空格,否则会被认为是正则
表达式分组(圆括号)
echo "Saturday" | gawk '/Sat(urday)?/{print $0}'
echo "cab" | gawk '/(c|b)a(b|t)/{print $0}'