Linux中正则表达式的应用

时间:2022-12-03 19:06:24

正则表达式说到底其实就是一个以行为单位进行字符串处理的方法,由于其强大的字符串处理能力,目前有很多软件都支持正则表达式操作。

注意,正则表达式跟之前我们说的通配符(wildchar)完全不是一回事哦,通配符是bash接口下的操作功能,而正则表达式是一种字符串处理的表达方式!比如在通配符中 * 代表的是任意个字符,而在正则表达式中

     . (小数点):代表『一定有一个任意字符』的意思;

     * (星星号):代表『重复前一个 字符 0 到无穷多次』的意思,为组合形态 ;

这样讲好像不太好懂,我们直接做个练习吧!假如我需要找出 g??d 的字符串,亦即共有四个字符, 起头是 g 而结束是 d ,我可以这样做:

[root@www ~]# grep -n 'g..d' regular_express.txt
1:"Open Source" is a good mechanism to develop programs.
9:Oh! The soup taste good.
16:The world <Happy> is the same with "glad".
再者,如果我想要列出有 oo, ooo, oooo 等等的数据, 也就是说,至少要有两个 o 以上,该如何是好?是 o
* 还是 oo*

因为 *代表癿是『重复 0 个或多个前面的 Repeat 字符』的意思, 因此,『o*』代表拥有0个字符或一个 o 以上的字符, 特别注意,因为允许空字符,因此,『 grep -n 'o*' regular_express.txt 』将会把所有数据都打印出到屏幕上!

那如果是『oo*』呢?则第一个 o 肯定必须要存在,第二个 o 则是可有可无的多个 o , 所以,凡是凡是有 o, oo, ooo, oooo 等等,都可以被列出~

同理,当我们需要『至少两个 o 以上的字符串』时,就需要 ooo* ,即:

[root@www ~]# grep -n 'ooo*' regular_express.txt
1:"Open Source" is a good mechanism to develop programs.
2:apple is my favorite food.
3:Football game is not use feet only.
9:Oh! The soup taste good.
18:google is the best tools for search keyword.
19:goooooogle yes!

这样理解 *的意义了吗?

ok,现在出个练习,如果我想要字符串开头不结尾都是 g,但是两个 g 之间仅能存在至少一个 o ,即是 gog, goog, gooog.... 等等,那该如何?

[root@www ~]# grep -n 'goo*g' regular_express.txt
18:google is the best tools for search keyword.
19:goooooogle yes!

再来一题,如果我想要找出 g 开头和 g 结尾的字符串,当中字符可有可无,那该如何是好?是『g*g』吗?

[root@www ~]# grep -n 'g*g' regular_express.txt
1:"Open Source" is a good mechanism to develop programs.
3:Football game is not use feet only.
9:Oh! The soup taste good.
13:Oh! My god!
14:The gd software is a library for drafting programs.
16:The world <Happy> is the same with "glad".
17:I like dog.
18:google is the best tools for search keyword.
19:goooooogle yes!
20:go! go! Let's go.

但测试结果竟然出现这么多行?太诡异了吧?这是因为 g*g 里面的 g* 代表『零个字符或一个以上的 g』 在加上后面的 g ,因此,整个 Repeat的内容就是 g, gg, ggg, gggg , 因此,只要该行当中拥有一个以上的 g 就符合正则表达式了!那该如何得到我们的 g....g 需求呢?呵呵!就利用任意一个字符『.』啊! 即是:『g.*g』写法,

因为 *可以是 0 或多个重复前面的字符,而 . 是任意字符,所以: 『.* 就代表零个或多个任意字符』的意思!

[root@www ~]# grep -n 'g.*g' regular_express.txt
1:"Open Source" is a good mechanism to develop programs.
14:The gd software is a library for drafting programs.
18:google is the best tools for search keyword.
19:goooooogle yes!
20:go! go! Let's go.

因为是代表 g 开头和 g 结尾,中间任意字符均可接受,所以,第 1, 14, 20 行也被显示了出来! 这个.*的 Repeat 表示任意字符是很常见的,希望大家能够理解并熟悉! 

在上个例题当中,我们可以利用.* Repeat 字符来设定 0 个到无限多个重复字符, 那如果我想要限制一个范围区间内的重复字符数呢?举例来说,我想要找出两个到五个 o 的连续字符串,该如何作?这时候就得要使用到限定范围的字符 {} 了。 但因为 { 和 } 的符号在 shell 是有特殊意义的,因此, 我们必须要使用跳脱字符 \ 来让他失去特殊意义才行。 至亍 {} 癿诧法是这样癿,假如我要找到两个 o 的字符串,可以是:

[root@www ~]# grep -n 'o\{2\}' regular_express.txt
1:"Open Source" is a good mechanism to develop programs.
2:apple is my favorite food.
3:Football game is not use feet only.
9:Oh! The soup taste good.
18:google is the best tools for search keyword.
19:goooooogle yes!

这样看似乎和 ooo*字符没有什么差异啊?因为第 19 行有多个 o 依旧也出现了! 那么换个搜寻的字符串,现在我们要找出 g 后面接 2 到 5 个 o ,然后再接一个 g 的字符串,他会是这样:

[root@www ~]# grep -n 'go\{2,5\}g' regular_express.txt

18:google is the best tools for search keyword.


现将基础的正则表达式特殊字符汇整如下:

^word
意义:待搜寻的字符串(word)在行首!
范例:搜寻行首为 # 开始的那一行,并列出行号 
grep -n '^#' regular_express.txt

word$
意义:待搜寻的字符串(word)在行尾!
范例:将行尾为 ! 的那一行打印出来 
grep -n '!$' regular_express.txt

.
意义:代表『一定有一个任意字符』的字符!
范例:搜寻的字符串可以是 (eve) (eae) (eee) (e e), 但不能仅有 (ee) !即 e 和 e 中间『一定』仅有一个字符,空格符也是字符! 
grep -n 'e.e' regular_express.txt

\
意义:转义字符,将特殊符号的特殊意义去除!
范例:搜索有单引号 ' 的那一行! 
grep -n \' regular_express.txt

*
意义:重复零个到无穷多个的前一个 RE 字符
范例:找出有 (es) (ess) (esss) 等等的字符串,注意,因为 * 可以是 0 个,所以es 也是符合带搜寻字符串。另外,因为 * 为重复『前一个 RE 字符』的符号, 因此,在 *之前必须要紧接着一个 RE 字符喔!例如任意字符则为 『.*』 ! 
grep -n 'ess*' regular_express.txt

[list]
意义:字符集合的 RE 字符,里面列出想要获取的字符!
范例:搜索有 (gl) 或 (gd) 的那一行,需要特别留意的是,在 [] 当中『仅代表一个待搜寻的字符』, 例如『 a[afl]y 』代表搜寻的字符串可以是 aay, afy, aly即[afl] 代表 a 或 f 或 l 的意思! 

grep -n 'g[ld]' regular_express.txt

[n1-n2]
意义:字符集合的 RE 字符,里面列出想要获取的字符范围!
范例:搜索有任意数字的那一行!需特别留意,在字符集合 [] 中的减号 - 代表两个字符之间的所有连续字符!但这个连续是与 ASCII 编码有关,因此,你的编码一定要设定正确(在 bash 当中,需要确定 LANG 和LANGUAGE 的变量是否正确!) 例如, LANG=C, 则所有大写字符则为 [A-Z] 
grep -n '[0-9]' regular_express.txt

[^list]
意义:字符集合的 RE 字符,里面列出不要的字符串和范围!
范例:搜索的字符串可以是 (oog) (ood) 但不能是 (oot) ,那个 ^ 在 [] 内时,代表『反向选择』的意思。 例如,我不要大写字符,则为 [^A-Z]。
grep -n 'oo[^t]' regular_express.txt

\{n,m\}
意义:连续 n 到 m 个的『前一个 RE 字符』
   若为 \{n\} 则是连续 n 个的前一个 RE 字符, 
  若是 \{n,\} 则是连续 n 个以上的前一个 RE 字符! 

范例:在 g 和 g 之间 2 个到 3 个 o 存在的字符串,即 (goog)(gooog) 

grep -n 'go\{2,3\}g' regular_express.txt