正则表达式和通配符
正则表达式和通配符是两个极易混淆的概念,通配符 (wildcard) 通常代表的是 Bash 操作接口的一个功能,但正规表示法则是一种字符串处理的表示方式。
1. 正则表达式
正则表示法就是处理字符串的方法,他是以行为单位来进行字符串的处理行为,正则表示法通过一些特殊符号的辅助,可以让使用者轻易的达到『搜索/删除/替换』某特定字符串的处理程序!
我们可以在 Notepad++ 或者 VIM 编辑器上采用以下文本文档进行实验,本文用的是 Bash 的 grep 命令。
"Open Source" is a good mechanism to develop programs.
apple is my favorite food.
Football game is not use feet only.
this dress doesn't fit me.
However, this dress is about $ 3183 dollars.
GNU is free air not free beer.
Her hair is very beauty.
I can't finish the test.
Oh! The soup taste good.
motorcycle is cheap than car.
This window is clear.
the symbol '*' is represented as start.
Oh! My god!
The gd software is a library for drafting programs.
You are the best is mean you are the no. 1.
The world <Happy> is the same with "glad".
I like dog.
google is the best tools for search keyword.
goooooogle yes!
go! go! Let's go.
# I am VBird
符号 | 描述 |
---|---|
^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 也是符合带c查找字符串。另外,因为* 为重复『前一个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 字符,里面列出想要撷取的字符范围! 范例:c查找含有任意数字的那一行!需特别留意,在字符集合[] 中的减号- 是有特殊意义的,他代表两个字符之间的所有连续字符!但这个连续与否与 ASCII 编码有关,因此,你的编码需要设定正确(在bash 当中,需要确定 LANG 与 LANGUAGE 的变量是否正确!) 例如所有大写字符则为[A-Z] grep -n '[A-Z]' regular_express.txt |
[^list] | 意义:字符集合的RE 字符,里面列出不要的字符串或范围! 范例:c查找的字符串可以是(oog) (ood) 但不能是(oot) ,那个^ 在[] 内时,代表的意义是『反向选择』的意思。例如,我不要大写字符,则为[^A-Z]。但是,需要特别注意的是,如果以grep -n [^A-Z] regular_express.txt 来c查找,却发现该文件内的所有行都被列出,为什么?因为这个[^A-Z] 是『非大写字符』的意思,因为每一行均有非大写字符,例如第一行的 “Open Source” 就有 p,e,n,o… 等等的小写字母 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 |
2. 通配符
在bash 的操作环境中还有一个非常有用的功能,那就是通配符(wildcard) !我们利用bash 处理数据就更方便了!底下我们列出一些常用的通配符:
表达式 | 描述 |
---|---|
* | 代表0个到无穷多个任意字符 |
? | 代表一定有一个任意字符 |
[] | 同样代表『一定有一个在括号内』的字符(非任意字符)。例如 [abcd] 代表『一定有一个字符,可能是 a, b,c, d 这四个任何一个』 |
[ - ] | 若有减号在中括号内时,代表『在编码顺序内的所有字符』。例如 [0-9] 代表 0 到 9 之间的所有数字,因为数字的语系编码是连续的! |
[^ ] | 若中括号内的第一个字符为指数符号(^) ,那表示『反向选择』,例如[^abc] 代表一定有一个字符,只要是非a, b, c 的其他字符就接受的意思。 |
3. 小结
再次强调:『正规表示法的特殊字符』与一般在指令列输入指令的『通配符』并不相同,例如,在通配符当中的 * 代表的是『 0 ~ 无限多个字符』的意思,但是在正规表示法当中,* 则是『重复到无穷多个的前一个 RE 字符』的意思~使用的意义并不相同,不要搞混了!
举例来说,不支持正规表示法的ls 这个工具中,若我们使用ls -l *
代表的是任意档名的文件,而ls -l a*
代表的是以a 为开头的任何档名的文件,但在正规表示法中,我们要找到含有以 a 为开头的文件,则必须要这样:(需搭配支持正规表示法的工具)
ls | grep -n '^a.*'
正则表达式与通配符都有很多应用场景,一般来说正则表达式的用法是比较具有通用性的如在 JavaScript 里 Java 里或是 Linux 的 Bash 命令中的正则表示法基本相同,但是在用通配符的时候最好注意区分,如 Spring 的 XML 配置文件中的通配符用法就不一定与 Linux 中的完全一致:
- 通配符的常见场景:
1.1. Spring配置文件
1.2. Linux的bash环境 - 正则表达式:
2.1. JS的字段校验
2.2. 文本编辑器(VIM)的查找替换
2.3. 邮件服务器的过滤垃圾邮件
2.4. 运维工程师进行系统日志查找和筛选
[参考]
[1]: 《鸟哥的Linux私房菜》