Shell脚本编程一直是Linux系统入门的必须课。最近决定将Linux shell 完整的学习一遍,学习的过程还是写些笔记来加深印象,这个系列就从正则表达式开始吧。
通俗来讲正则表达式就是定义了一组规则,以用来过滤,替换某些特定的字符串。比如说,我们用记事本打开一份log文件,并利用关键字搜索特定的log,这里的关键字就可以看成是正则表达式。当然我们将要介绍的正则表达式基于linux系统,并且使用一些通配符来定义规则。
正则表达式就是:regular expression,简称BRE,后面介绍的扩展正则表达式简称为ERE。
1. 基本正则表达式
我们当然也可以将正则表达式类比为由某些特定的语法构成,这样我们可以简单的将这种用法归纳为:位置相关,字符相关,次数相关以及分组与后向引用这四大类。
1.1 位置相关
位置相关的字符如下:
- ^:表示行首,此字符后面的任意内容必须出现在行首才能匹配;
- $:表示行尾,此字符前面的任意内容必须出现在行尾才能匹配;
- ^$:表示匹配空行,这里所描述的空行表示"回车";
- \<或者\b :匹配单词边界,表示词首,其后面的字符必须作为单词首部出现;
- \>或者\b :匹配单词边界,表示词尾,其前面的字符必须作为单词尾部出现;
- \B:匹配非单词边界,与\b正好相反。
1.2 字符相关
字符相关的格式如下:
- . : 表示任意单个字符;
- \ :表示转义符,当与正则表达式中的符号结合时表示符号本身;
- [ ] :表示匹配指定范围内的任意单个字符;
- [^ ] :表示匹配范围外的任意单个字符,比如 [^[:alpha:]] 表示单个非字母字符;
- [[:alpha:]] :等效与[a-zA-Z],表示任意大小写字母;
- [[:lowe:]] :等效与[a-z] ,表示任意小写字母;
- [[:upper:]] :等效与[A-Z],表示任意大写字母;
- [[:digit:]] :等效于[0-9], 表示0到9之间的任意单个数字(包括0和9);
- [[:alnum:]] :等效于[a-zA-Z0-9], 表示任意数字或字母;
- [[:space:]] :表示任意空白字符,包括"空格"、"tab键"等;
- [[:punct:]] :表示任意标点符号;
另外还有一些简单的字符格式:
- \d :表示任意单个0到9的数字;
- \D :表示任意单个非数字字符;
- \t :表示匹配单个横向制表符(相当于一个tab键);
- \s :表示匹配单个空白字符,包括"空格","tab制表符"等;
- \S :表示匹配单个非空白字符;
看到这里应该也可以注意到,一般大写字母就是对其对应小写字母取反操作。
1.3 次数相关
匹配次数相关的字符有:
- * :表示前面的字符连续出现任意次,包括0次;
- * :表示任意长度的任意字符,与通配符中的*的意思相同;
- \? :表示匹配其前面的字符0或1次;
- \+ :表示匹配其前面的字符至少1次,或者连续多次,连续次数上不封顶;
- \{n\} : 表示前面的字符连续出现n次,将会被匹配到;
- \{x,y\} :表示之前的字符至少连续出现x次,最多连续出现y次;
- \{,n\} :表示之前的字符连续出现至多n次,最少0次,都会陪匹配到;
- \{n,\} :表示之前的字符连续出现至少n次,才会被匹配到
1.4 分组与后向引用
我们再来看看分组和引用的含义:
1. 分组
分组的表示方法为:
\( \) :我们可以将其中的内容当做一个整体,比如\(ab\) 表示将ab当做一个整体去处理分组也可以嵌套;
分组其实很好理解,比如:“ab\{2\}” 这个正则表达式,“ab”,”abb”,”abbb”都能匹配上,但是”abab”就不行;如果改成”\(ab\)”, 那“abab”就可以正确匹配。
分组的意思就是将括号内的字符作为一个整体去匹配。而嵌套分组的意思就是一个分组中可以包含另外的分组。比如,”\(\(ab\){2}c\){3}”。
2. 后向引用
后向引用的表示方式也很简单:
\n : 表示后向引用,引用整个表达式中第n个分组中的正则匹配到的结果。
后向引用概念说起来难以理解,我们还是先来看一个示例吧:如果想查找一个包含有”hello world hello”的字符串,怎么用正则表达式来去匹配呢?
grep “hello world hello” filename?
当然可以!有没有更简单一点的写法?当然也有:
grep “(hello) world \1”
这里的\1就是后向引用,讲到这里大家应该已经明白,后向引用就是用”\n”的写法去替代前面的第n个分组。这里的第n个分组怎么界定呢?再来看个例子:
\(ab\(cd\)\(ef\)\)
这里的\(ab….\)就是第一个分组,也就是\1;\(cd\)和\(ef\)分别就是第二个分组,第三个分组,分别是\2,\3。相信大家应该也找到规律了,就是按照”(”的 先后顺序来排的。
关于后向引用还有一点要强调的是:一定要对分组后向引用。没有”()”, 是不能对其后向引用的。
2. 扩展正则表达式
2.1 扩展正则表达式
扩展正则表达式顾名思义就是对普通的正则表达式进行了扩展。可以使用正则表达式的命令一般也提供了使用哪种正则表达式的选项。比如对应grep命令来说,默认就是使用普通的BRE,如果使用”-E” 或者egrep就是使用扩展正则表达式。其实ERE使用的通配符与BRE基本上都是一样的,主要区别呢就是以下两点:
1. 对于转义字符”\”的使用
ERE中”()”和”{}”前面都不用再加”\”转义,这个可是一个巨大的改进,让正则表达式的书写和阅读都更容易;
2. ERE增加了一个“或选项”,就是“|”
“|”就是一个或的条件,比如(com|net),表示是com或者net 就符合条件,不要小看它,很实用的。