正则表达式详解释

    这个文件的位置
    wget http://linux.vbird.org/linux_basic/0330regularex/regular_express.txt
    文件的内容

    1. [dmtsai@study ~]$ vi regular_express.txt
    2. "Open Source" is a good mechanism to develop programs.
    3. apple is my favorite food.
    4. Football game is not use feet only.
    5. this dress doesn't fit me.
    6. However, this dress is about $ 3183 dollars.^M
    7. GNU is free air not free beer.^M
    8. Her hair is very beauty.^M
    9. I can't finish the test.^M
    10. Oh! The soup taste good.^M
    11. motorcycle is cheap than car.
    12. This window is clear.
    13. the symbol '*' is represented as start.
    14. Oh! My god!
    15. The gd software is a library for drafting programs.^M
    16. You are the best is mean you are the no. 1.
    17. The world <Happy> is the same with "glad".
    18. I like dog.
    19. google is the best tools for search keyword.
    20. goooooogle yes!
    21. go! go! Let's go.
    22. # I am VBird

    例题一、搜寻特定字串搜寻特定字串很简单吧?假设我们要从刚刚的文件当中取得 the 这个特定字串,最
    简单的方式就是这样:

    [dmtsai@study ~]$ grep -n 'the' regular_express.txt 
    8:I can't finish the test. 
    12:the symbol '*' is represented as start. 
    15:You are the best is mean you are the no. 1. 
    16:The world <Happy> is the same with "glad". 
    18:google is the best tools for search keyword.
    

    那如果想要“反向选择”呢?也就是说,当该行没有 ‘the’ 这个字串时才显示在屏幕
    上,那就直接使用:

    [dmtsai@study ~]$ grep -vn 'the' regular_express.txt 
    你会发现,屏幕上出现的行列为除了 8,12,15,16,18 五行之外的其他行列! 接下 
    来,如果你想要取得不论大小写的 the 这个字串,则: 
    [dmtsai@study ~]$ grep -in 'the' regular_express.txt 
    8:I can't finish the test. 
    9:Oh! The soup taste good. 
    12:the symbol '*' is represented as start. 
    14:The gd software is a library for drafting programs. 
    15:You are the best is mean you are the no. 1. 
    16:The world <Happy> is the same with "glad". 
    18:google is the best tools for search keyword.
    

    除了多两行 (9, 14行) 之外,第 16 行也多了一个 The 的关键字被撷取到喔!
    例题二、利用中括号 [] 来搜寻集合字符
    如果我想要搜寻 test 或 taste 这两个单字时,可以发现到,其实她们有共通的 ‘t?st’
    存在~这个时候,我可以这样来搜寻:
    [dmtsai@study ~]$ grep -n ‘t[ae]st’ regularexpress.txt
    8:I can’t finish the test. 9:Oh! The soup taste good.
    了解了吧?其实 [] 里面不论有几个字符,他都仅代表某“一个”字符, 所以,上面
    的例子说明了,我需要的字串是“tast”或“test”两个字串而已! 而如果想要搜寻到有 oo 的
    字符时,则使用:
    [dmtsai@study ~]$ grep -n ‘oo’ 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!
    但是,如果我不想要 oo 前面有 g 的话呢?此时,可以利用在集合字符的反向选择[^] 来达成:
    [dmtsai@study ~]$ grep -n ‘[^g]oo’ regular_express.txt 2:apple is my favorite food. 3:Football game is not use feet only. 18:google is the best tools for search keyword. 19:goooooogle yes!
    意思就是说,我需要的是 oo ,但是 oo 前面不能是 g 就是了!仔细比较上面两个
    表格,你会发现,第 1,9 行不见了,因为 oo 前面出现了 g 所致!第 2,3 行没有疑问,因为
    foo 与 Foo 均可被接受!但是第 18 行明明有 google 的 goo 啊~别忘记了,因为该行后面
    出现了 tool 的 too 啊!所以该行也被列出来~ 也就是说, 18 行里面虽然出现了我们所不
    要的项目 (goo) 但是由于有需要的项目 (too) , 因此,是符合字串搜寻的喔!
    至于第 19 行,同样的,因为 goooooogle 里面的 oo 前面可能是 o ,例如:
    go(ooo)oogle ,所以,这一行也是符合需求的!
    再来,假设我 oo 前面不想要有小写字符,所以,我可以这样写 [^abcd….z]oo , 但
    是这样似乎不怎么方便,由于小写字符的 ASCII 上编码的顺序是连续的, 因此,我们可
    以将之简化为下面这样:
    [dmtsai@study ~]$ grep -n ‘[^a-z]oo’ regular_express.txt 3:Football game is not use feet only.
    也就是说,当我们在一组集合字符中,如果该字符组是连续的,例如大写英文/小
    写英文/数字等等, 就可以使用[a-z],[A-Z],[0-9]等方式来书写,那么如果我们的要求字串
    是数字与英文呢? 呵呵!就将他全部写在一起,变成:[a-zA-Z0-9]。例如,我们要取得
    有数字的那一行,就这样:
    [dmtsai@study ~]$ grep -n ‘[0-9]’ regular_express.txt 5:However, this dress is about $ 3183 dollars. 15:You are the best is mean you are the no. 1.
    但由于考虑到语系对于编码顺序的影响,因此除了连续编码使用减号“ - ”之外,
    你也可以使用如下的方法来取得前面两个测试的结果:
    [dmtsai@study ~]$ grep -n ‘[^[:lower:]]oo’ regular_express.txt
    # 那个 [:lower:] 代表的就是 a-z 的意思!请参考前两小节的说明表格
    [dmtsai@study ~]$ grep -n ‘[[:digit:]]’ regular_express.txt
    啥?上头在写啥东西呢?不要害怕!分开来瞧一瞧。我们知道 [:lower:] 就是 a-z 的
    意思,那么 [a-z] 当然就是 [[:lower:]] 啰!鸟哥第一次接触正则表达式的时候,看到两层
    中括号差点昏倒~完全看不懂!现在,请注意那个叠代的意义, 自然就能够比较清楚了
    解啰!这样对于 [] 以及 [^] 以及 [] 当中的 - ,还有关于前面表格提到的特殊关键字有了解
    了吗?^
    ^!
    例题三、行首与行尾字符 ^ $
    我们在例题一当中,可以查询到一行字串里面有 the 的,那如果我想要让 the 只在
    行首列出呢? 这个时候就得要使用定位字符了!我们可以这样做:
    [dmtsai@study ~]$ grep -n ‘^the’ regularexpress.txt 12:the symbol ‘‘ is represented as start.
    此时,就只剩下第 12 行,因为只有第 12 行的行首是 the 开头啊~此外, 如果我
    想要开头是小写字符的那一行就列出呢?可以这样:
    [dmtsai@study ~]$ grep -n ‘^[a-z]’ regular_express.txt 2:apple is my favorite food. 4:this dress doesn’t fit me. 10:motorcycle is cheap than car. 12:the symbol ‘
    ‘ is represented as start. 18:google is the best tools for search keyword. 19:goooooogle yes! 20:go! go! Let’s go.
    你可以发现我们可以捉到第一个字符都不是大写的!上面的指令也可以用如下的
    方式来取代的:
    [dmtsai@study ~]$ grep -n ‘^[[:lower:]]’ regular_express.txt 好!那如果我不想要开头是英文字母,则可以是这样: [dmtsai@study ~]$ grep -n ‘^[^a-zA-Z]’ regular_express.txt 1:”Open Source” is a good mechanism to develop programs. 21:# I am VBird
    # 指令也可以是: grep -n ‘^[^[:alpha:]]’ regular_express.txt
    注意到了吧?那个 ^ 符号,在字符集合符号(括号[])之内与之外是不同的! 在 []
    内代表“反向选择”,在 [] 之外则代表定位在行首的意义!要分清楚喔! 反过来思考,那
    如果我想要找出来,行尾结束为小数点 (.) 的那一行,该如何处理:
    [dmtsai@study ~]$ grep -n ‘.$’ 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. 4:this dress doesn’t fit me. 10:motorcycle is cheap than car. 11:This window is clear. 12:the symbol ‘‘ is represented as start. 15:You are the best is mean you are the no. 1. 16:The world is the same with “glad”. 17:I like dog. 18:google is the best tools for search keyword.
    20:go! go! Let’s go.特别注意到,因为小数点具有其他意义(下面会介绍),所以必须要使用跳脱字
    符(\)来加以解除其特殊意义! 不过,你或许会觉得奇怪,但是第 5~9 行最后面也是 .
    啊~怎么无法打印出来? 这里就牵涉到 Windows 平台的软件对于断行字符的判断问题
    了!我们使用 cat -A 将第五行拿出来看, 你会发现:
    [dmtsai@study ~]$ cat -An regular_express.txt | head -n 10 | tail -n 6 5 However, this dress is about $ 3183 dollars.^M$ 6 GNU is free air not free beer.^M$ 7 Her hair is very beauty.^M$ 8 I can’t finish the test.^M$ 9 Oh! The soup taste good.^M$ 10 motorcycle is cheap than car.$
    我们在第九章内谈到过断行字符在 Linux 与 Windows 上的差异, 在上面的表格中
    我们可以发现 5~9 行为 Windows 的断行字符 (^M$) ,而正常的 Linux 应该仅有第 10
    行显示的那样 ($) 。所以啰,那个 . 自然就不是紧接在 $ 之前喔!也就捉不到 5~9 行
    了!这样可以了解 ^ 与 $ 的意义吗? 好了,先不要看下面的解答,自己想一想,那么如
    果我想要找出来,哪一行是“空白行”, 也就是说,该行并没有输入任何数据,该如何搜
    寻?
    [dmtsai@study ~]$ grep -n ‘^$’ regular_express.txt 22:
    因为只有行首跟行尾 (^$),所以,这样就可以找出空白行啦!再来,假设你已
    经知道在一个程序脚本 (shell script) 或者是配置文件当中,空白行与开头为 # 的那一行
    是注解,因此如果你要将数据列出给别人参考时, 可以将这些数据省略掉以节省保贵的
    纸张,那么你可以怎么作呢? 我们以 /etc/rsyslog.conf 这个文件来作范例,你可以自行参
    考一下输出的结果:
    [dmtsai@study ~]$ cat -n /etc/rsyslog.conf # 在 CentOS 7 中,结果可以发现有 91 行的输出,很多空白行与 # 开头的注解行 [dmtsai@study ~]$ grep -v ‘^$’ /etc/rsyslog.conf | grep -v ‘^#’ # 结果仅有 14 行,其中第一个“ -v ‘^$’ ”代表“不要空白行”, # 第二个“ -v ‘^#’ ”代表“不要开头是 # 的那行”喔!
    是否节省很多版面啊?另外,你可能也会问,那为何不要出现 # 的符号的那行就
    直接舍弃呢?没办法!因为某些注解是与设置写在同一行的后面, 如果你只是抓 # 就予
    以去除,那就会将某些设置也同时移除了!那错误就大了~
    例题四、任意一个字符 . 与重复字符

    在第十章 bash 当中,我们知道万用字符 可以用来代表任意(0或多个)字符,
    但是正则表达式并不是万用字符,两者之间是不相同的! 至于正则表达式当中的“ . ”则代
    表“绝对有一个任意字符”的意思!这两个符号在正则表达式的意义如下:.
    (小数点):代表“一定有一个任意字符”的意思;
    (星星号):代表“重复前一个字符, 0 到无穷多次”的意思,为组合形态
    这样讲不好懂,我们直接做个练习吧!假设我需要找出 g??d 的字串,亦即共有四
    个字符, 起头是 g 而结束是 d ,我可以这样做:
    [dmtsai@study ~]$ 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 is the same with “glad”.
    因为强调 g 与 d 之间一定要存在两个字符,因此,第 13 行的 god 与第 14 行的 gd
    就不会被列出来啦!再来,如果我想要列出有 oo, ooo, oooo 等等的数据, 也就是说,至
    少要有两个(含) o 以上,该如何是好?是 o 还是 oo 还是 ooo* 呢? 虽然你可以试看
    看结果, 不过结果太占版面了 @
    @ ,所以,我这里就直接说明。
    因为 代表的是“重复 0 个或多个前面的 RE 字符”的意义, 因此,“o”代表的
    是:“拥有空字符或一个 o 以上的字符”, 特别注意,因为允许空字符(就是有没有字符
    都可以的意思),因此,“ grep -n ‘o‘ regular_express.txt ”将会把所有的数据都打印出来屏
    幕上!
    那如果是“oo
    ”呢?则第一个 o 肯定必须要存在,第二个 o 则是可有可无的多个 o
    , 所以,凡是含有 o, oo, ooo, oooo 等等,都可以被列出来~
    同理,当我们需要“至少两个 o 以上的字串”时,就需要 ooo ,亦即是:
    [dmtsai@study ~]$ 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!
    这样理解 的意义了吗?好了,现在出个练习,如果我想要字串开头与结尾都是
    g,但是两个 g 之间仅能存在至少一个 o ,亦即是 gog, goog, gooog…. 等等,那该如何?
    [dmtsai@study ~]$ grep -n ‘goo
    g’ regular_express.txt 18:google is the best tools for search keyword. 19:goooooogle yes!
    如此了解了吗?再来一题,如果我想要找出 g 开头与 g 结尾的字串,当中的字符
    可有可无,那该如何是好?是“gg”吗?
    [dmtsai@study ~]$ 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 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.
    但测试的结果竟然出现这么多行?太诡异了吧?其实一点也不诡异,因为 gg 里
    面的 g
    代表“空字符或一个以上的 g” 在加上后面的 g ,因此,整个 RE 的内容就是 g, gg,
    ggg, gggg , 因此,只要该行当中拥有一个以上的 g 就符合所需了!
    那该如何得到我们的 g….g 的需求呢?呵呵!就利用任意一个字符“.”啊! 亦即
    是:“g.g”的作法,因为 可以是 0 或多个重复前面的字符,而 . 是任意字符,所以: “.
    就代表零个或多个任意字符”的意思啦!
    [dmtsai@study ~]$ 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 行是可
    接受的喔! 这个 . 的 RE 表示任意字符是很常见的,希望大家能够理解并且熟悉! 再出
    一题,如果我想要找出“任意数字”的行列呢?因为仅有数字,所以就成为:
    [dmtsai@study ~]$ grep -n ‘[0-9][0-9]
    ‘ regular_express.txt 5:However, this dress is about $ 3183 dollars. 15:You are the best is mean you are the no. 1.
    虽然使用 grep -n ‘[0-9]’ regular_express.txt 也可以得到相同的结果, 但鸟哥希望大
    家能够理解上面指令当中 RE 表达式的意义才好!
    例题五、限定连续 RE 字符范围 {}
    在上个例题当中,我们可以利用 . 与 RE 字符及 来设置 0 个到无限多个重复字
    符, 那如果我想要限制一个范围区间内的重复字符数呢?举例来说,我想要找出两个到
    五个 o 的连续字串,该如何作?这时候就得要使用到限定范围的字符 {} 了。 但因为 { 与
    } 的符号在 shell 是有特殊意义的,因此, 我们必须要使用跳脱字符 \ 来让他失去特殊意
    义才行。 至于 {} 的语法是这样的,假设我要找到两个 o 的字串,可以是:
    [dmtsai@study ~]$ 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
    的字串,他会是这样:
    [dmtsai@study ~]$ grep -n ‘go{2,5}g’ regular_express.txt 18:google is the best tools for search keyword.
    嗯!很好!第 19 行终于没有被取用了(因为 19 行有 6 个 o 啊!)。 那么,如果
    我想要的是 2 个 o 以上的 goooo….g 呢?除了可以是 gooog ,也可以是:
    [dmtsai@study ~]$ grep -n ‘go{2,}g’ regular_express.txt 18:google is the best tools for search keyword. 19:goooooogle yes!
    *扩展 正则

    image.jpeg
    以上这些就是延伸型的正则表达式的特殊字符。另外,要特别强调的是,那个 ! 在
    正则表达式当中并不是特殊字符, 所以,如果你想要查出来文件中含有 ! 与 > 的字行
    时,可以这样:
    grep -n ‘[!>]’ regular_express.txt