Linux Shell以一串字符作为表达式向系统传达意思。元字符(Metacharacters)是用来阐释字符表达式意义的字符,简言之,元字符就是描述字符的 字符,它用于对字符表达式的内容、转换及各种操作信息进行描述。正则表达式是由一串字符和元字符构成的字符串,简称RE(Regular Expression)。正则表达式的主要功能是文本查询和字符串操作,它可以匹配文本的一个字符或字符集合。
在 Linux 系统中,程序设计语言Java、Perl和Python等,Shell工具sed、awk和grep等,MySQL 和PostgreSQL 等数据库服务器都使用了正则表达式,图3-1 描述了正则表达式用于数据流处理的过程,实际上,正则表达式完成了数据过滤,将不满足正则表达式定义的数据拒绝掉,剩下与正则表达式匹配的数据。
图3-1 正则表达式处理数据过程 |
正则表达式的基本元素包括普通字符和元字符,例如,a、b、1、2 等字符属于普通字符,普通字符可以按照字面意思理解,如:a 只能理解为英文的小写字母a,没有其他隐藏含义。而*、^、[]等元字符,Shell赋予了它们超越字面意思的意义,如:*符号的字面意义只是一个符号, 而实际上却表示了重复前面的字符0 次或多次的隐藏含义。因此,掌握正则表达式基本元素主要是对正则表达式中元字符意义的掌握。
POSIX 标准将正则表达式分为两类:基本的正则表达式和扩展的正则表达式,大部分Linux 应用和工具仅支持基本的正则表达式,因而,本节所述的正则表达式基础是掌握正则
表达式的关键,表3-1 列出了基本的正则表达式中元字符集合及其意义。
表3-1 基本的正则表达式元字符集合及其意义
续表
下面逐个介绍正则表达式元字符的意义和用法,并举一些例子结合使用元字符集合。
1."*"符号
"*"符号用于匹配前面一个普通字符的0 次或多次重复,如:
- #例3-1:*符号的意义
- hel*o
"*"符号前面的普通字符是l,*字符就表示匹配l 字符0 次或多次,如字符串helo、hello、hellllllo都可以由hel*o来表示。
2."."符号
点号"."用于匹配任意一个字符,如:
- #例3-2:.符号的意义
- …73.
由于"."符号只能匹配一个字符,因此,上述字符串表示前面三个字符为任意字符,第4 和第5 个字符是7和3,最后一个字符为任意字符,如xcb738、4J973U都能匹配上述字符串。值得注意的是,"."符号可以匹配一个空格,因此,x b738、ui 73e也能匹配上述字符串。
3."^"符号
"^"符号用于匹配行首,表示行首的字符是"^"字符后面的那个字符,如:
- #例3-3:^符号的意义
- ^cloud
这表示匹配以cloud开头的行。结合上面介绍的"*"符号和"."符号,再举一个例子:
- #例3-4:^符号、.符号和*符号结合使用
- ^…X86*
该字符串表示行首的三个字符为任意字符(可以是空格),第4~6 个字符为X86,第7个字符开始可以重复匹配6,如:866X86666、8 6X86都可以匹配上述字符串。
4."$"符号
$符号匹配行尾,$符号放在匹配字符之后,与"^"符号的功能和用法都相反,如:
- #例3-5:$符号的意义
- micky$
该正则表达式表示匹配以micky结尾的所有行。一个特殊的正则表达式是匹配所有空行的表达式,为:
- #例3-6:空行的表示方法
- ^$
该正则表达式既匹配行首,又匹配行尾,中间没有任何字符,因此,为空行。读者需要牢记例3-6 所示的空行表示方法,很多命令都用到这个正则表达式来表示空行。
如果需要匹配只包含一个字符的行,如下面的例3-7所示:
- #例3-7:包含一个字符的行
- ^.$
5."[]"符号
方括号[]匹配字符集合,该符号支持穷举方法列出字符集合的所有元素,也支持使用"-"符号表示字符集合范围,表明字符集合范围从"-"左边字符开 始,到"-"右边字符结束。如果要匹配任意一个数字,可以使用如例3-8 所示的两种方法,前一种穷举了阿拉伯数字,后一种用数字范围表示,显得比较简洁。
- #例3-8:匹配任意一个数字
- [0123456789]
- [0-9]
"[]"也可以用做字母匹配,例3-9给出了匹配字母的例子:
- #例3-9:匹配字母
- [a-z] #所有小写字母
- [A-Z] #所有大写字母
- [b-p] #小写字母b~p
- Linux 系统对大小写是敏感的,并且支持字母排序,因此,Linux 中有大写字母序列和小写字母序列,两者是分开的,例3-9 中a~z 表示所有的小写字母,A~Z 表示所有的大写字母,而b~p表示从b到p之间所有的小写字母。
我们知道,"^"符号表示匹配行首,但是,"^"符号放到"[]"符号中就不再表示匹配行首了,而是表示取反符号,请看下面的例3-10。
- #例3-10:^表示取反
- [^b-d]
- #例3-11:匹配所有的英文单词
- [A-Za-z] [A-Za-z]*
例3-11 的正则表达式表示以任意一个字母开头,再以任意字母进行0 次或任意次重复,实际上,这个正则表达式可以匹配任意英文单词。
6."\"符号
"\"符号是转义符,用于屏蔽一个元字符的特殊意义,即以字面含义来解释"\"符号后面的元字符,如:
- #例3-12:转义符
- \.
反斜杠后面的字符"."是元字符,经过转义后,"."不再表示任意一个字符,而是一个普通字符句号"."。转义符"\"是引用符的一种,我们将在6.2.3 节深入讨论它,在此不再展开论述。
7."\<\>"符号
"\<\>"符号是精确匹配符号,该符号利用"\"符号屏蔽"<>"符号,如:
- #例3-13:精确匹配
- \<the\>
该正则表达式精确匹配the 这个单词,而不匹配包含the 字符的单词,如them、there、another 等。
8."\{\}"系列符号
"\{\}"系列符号与"*"符号类似,都是表示前一个字符的重复。但是,"*"符号表示重复0 次或任意次,而"\{\}"系列符号可以指定重复次数,"\{\}"系列符号包括以下三种形式。
\{n\}:匹配前面字符出现n次。
\{n,\}:匹配前面字符至少出现n次。
\{n,m\}:匹配前面字符出现n~m次。
请看下面的例3-14。
- #例3-14:\{\}系列符号的用法
- JO\{3\}B #重复字符O 3 次
- JO\{3,\}B #重复字符O 至少3次
- JO\{3,6\}B #重复字符O 3~6次
JO\{3\}B表示重复字符O 3次,匹配值为:JOOOB。
JO\{3,\}B 表示重复字符O 至少3 次,JOOOB、JOOOOB、JOOOOOB 等字符串都可由该正则表达式来匹配。
JO\{3,6\}B表示重复字符O 至少3 次,至多6次,JOOOB、JOOOOOOB等字符串都满足,但是JOOB、JOOOOOOOB等字符串就不满足。
再举一个例子:
- #例3-15:精确匹配5个小写字母
- [a-z] \{5\}