一、什么是正则表达式
正则表达式是通过一些特殊的字符的排列,用以查找、替换、删除一行或多行文字字符串。正则表达式并不是一个工具程序,而是一种字符处理的标准依据,如果想要使用表达式的方式处理字符串,就得使用支持正则表达式的工具程序才行,这类的工具程序很多,例如vi,sed,awk等。
简单来说,正则表达式就是处理字符的方法,它是以行为单位来进行字符串的处理行为,正则表达式通过一些特殊符号的辅助,可以让用户轻易达到查找、删除、替换某特定字符串的处理程序。
注意:正则表达式与通配符是完全不一样的东西,因为通配符代表的是bash操接口的一个功能,但正则表达式则是一种字符串处理的表达方式!
同时,正则表达式的字符串表达方式依照不同的严谨程度而分为基础正则表达式与扩展正则表达式。本篇文章主要讲的是基础正则表达式,其余内容会在接下来的文章进行讲解。
二、grep的用法
grep是一个很常见也很常用的命令,它最重要的功能就是进行字符串数据的对比,然后将符合用户需求的字符串打印出来。需要说明的是grep在数据中查找一个字符串时,是以整行为单位来进行数据的选取的!也就是说,假如一个文件内有10行,其中有两行具有你所查找的字符串,则将那两行显示在屏幕上,其他的就丢弃了。
接下来我们以如下的txt文件做练习:
1、查找特定字符串
如果想要反向选择呢?也就是说当该行没有‘they’这个字符串时才显示在屏幕上,那就直接使用:
如果你想要取得无论大小写的‘they’这个字符串,则:
2、利用中括号[]来查找集合字符
如果我想要查找they和两个单词时,可以发现,其实他们有共同的‘the?’存在,这个时候我们可以这样进行查找:
其实[]里无论有几个字符,它其实只代表“一个”字符,那如果我们想要查到有he字符时,则使用:
如果我不希望he前面有t的话,此时,可以利用在集合字符的反向选择[^]来完成:
如果我不希望he的前面有小写字母怎么办呢?我们可以这样写[^abcd....z]he,但这样似乎不太方便,由于小写字符的ASCII上编码的顺序是连续的,因此,我们可以简化成这样写:
但由于考虑到语系对于编码的影响,因此除了连续编码使用‘-’以外,也可以使用如下方式进行
3、行首与行尾字符^和$
假如我想要The只出现在行首呢?这个时候就需要使用制表符了!我们可以这样做:
如果我想要开头是小写字符的那一行列出怎么办呢?我们可以这样:
那如果我不想开头是英文字母的话,该怎么办呢?
注意到了吧!这个^符号在[]内代表的是“反向选择”,在[]外代表的是定位在行首的意义,要分清楚。反过来思考,那如果我想要找出行尾结束为小数点.的那一行,该如何处理呢?
4、任意一字符.与重复字符*
在bash当中,我们知道通配符*可以用来代表(0或多个)字符,但是正则表达式并不是通配符,两者之间是不相同的。让我们看看正则表达式中是什么意思吧!
.(小数点):代表一定有一个任意字符的意思。
*(星号):代表重复前一个0到无穷多次的意思,为组合形态。
举个例子,假设我们要找出Th??e的字符串,也就是共有五个字符,开头是T,而结束是d,我们可以这样做:
假设我们需要找至少两个e以上的字符串时,就需要eee*,我们可以这样做:
三、基础正则表达式字符集合
(1)^a:查找的字符串(a)在行首
(2)a$:查找的字符串(a)在行尾
(3). : 代表一定有一个任意字符
(4)\ :转义符,将特殊符号的特殊意义去除
(5)*:重复零个到无穷多个的前一个RE字符
(6)[a]:字符集合的RE字符,里面列出想要选取的字符
(7)[a1-a2]:字符查找的集合,里面列出想要选取的字符范围
(8)[^a]:字符集合的RE字符,里面列出不要的字符串或范围
(9)\{n,m\}:连续n到m个前一个RE字符;若为\{n\},则是连续n个的前一个RE字符;若为\{n,\}则是连续n个以上的前一个RE字符
再次强调:正则表达式的特殊字符与一般在命令行输入命令的通配符并不相同,在通配符中的*代表的是0~无限个字符的意思,但是在正则表达式当中,*则是重复0到无穷多个的前一个RE字符的意思,使用的意义并不相同,不要搞混了。
举例来说,若我们使用ls -l *,代表的是任意文件名的文件,而ls -l a*代表的是以a为开头的任何文件名的文件,但在正则表达式中,我们要找到含有以a为开头的文件,则必须要这样:ls | grep -n '^a.*'
谢谢大家!