正则表达式 组合与锚点

单字符正则表达式的组合

串结

abc串结在一起,可以匹配abc本身。
[A-Z].[0-9].串结在一起,可以匹配AA00

星号(*)

单字符正则表达式后跟*,表示匹配这个单字符正则表达式的0次或任意多次。
例:正则表达式12*4
与字符串1234不匹配,与1224,12224,14匹配

例:正则表达式[A-Z][0-9]*
此例中*作用的单字符正则表式为[0-9],代表

1
2
3
4
5
[A-Z]
[A-Z][0-9]
[A-Z][0-9][0-9]
[A-Z][0-9][0-9][0-9]
......

这与A,A1,C45,D768匹配,与b64512,T56t不匹配。

例:正则表达式[Cc]hapter *[1-4]
在*号前有一个空格,允许数字1-4之前有多个或者0个空格。可匹配Chapter2,chapter 3等等。
例:正则表达式a\[i] *= *b\[j] *\* *c\[k]
匹配字符串a[i]=b[j]*c[k],容许等号和星号两侧有空格

例:在vi中使用正则表达式
:1,$s/[0-9]*/xx/g1,$表示从第1行到最后一行,s/[0-9]*/_/g表示把一行的所有的数字全部替换成_
需要注意的是

1
2
3
123 123 234 123 
a b c
hello2 hello3 hello4

替换结果:

1
2
3
_ _ _ _ 
_a_ _b_ _c
_h_e_l_l_o_ _h_e_l_l_o_ _h_e_l_l_o_

需要注意的是当没有数字的时候,[0-9]*可以匹配0次,这将匹配到一个空字符串,在一行中,任何两个字符之间都认为有一个空字符串。
所以替换的结果就是在任何两个字符之间添加一个_字符。这可能不是我们所希望的,在使用的时候应该多注意星号*匹配0次的情况。

锚点:$与^

锚点表示要匹配的字符串必须处于的位置。

$在尾部时有特殊意义,否则与其自身匹配

例:123$匹配文件中行尾的123,不在行尾的123字符不匹配
例:$123与字符串$123匹配
例:.$匹配行尾的任意字符

^在首部时有特殊意义,否则与其自身匹配

例:^printf匹配行首的printf字符串,不在行首的printf串不匹配
例:Hel^lo与字符串Hel^lo匹配
例:在vi中使用 :1,$s/^----//g表示删除第一行到最后一行的每行行首的4个减号-

1
2
3
0123456789
----hello
--------world

替换结果:

1
2
3
0123456789
hello
----world

正则表达式扩展

ERE:扩展的正则表达式(ERE)
PCRE: Perl-compatible regular expression

对基本正则表达式(BRE)进行了改进:

  • 添加分组:圆括号() :
    • (xy)*可匹配空字符串,xyxyxyxyxyxy
  • 添加逻辑运算:表示逻辑“或” 的符号 |
    • (pink|green)表示与pink或green匹配
  • 复次数定义:与星号地位类似的+和?,限定重复次数 {m,n}
    • *号表示它左边的单字符正则表达式重复的0次或多次
    • +号表示重复1次或多次:
      • [0-9]+:匹配长度至少为1数字串
    • ?表示0次或一次:
      • a?:匹配零个或一个a
    • 限定重复次数\{m,n\},例如:
      • [1-9][0-9]\{6,8\}:7-9位数字,首位非0
  • 命名的预定义集合
    • [[:xdigit:]]:十六进制数字
    • \d:数字
    • \D:非数字
  • ^$更灵活的锚点定义
    • 例如:寻找一个数字串,但是要求这个数字串不许出现在“合计”两个字之后