正则表达式语法小结

正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。正则表达式通常被用来检索、替换符合模式的文本。正则表达式最早出现在出现在理论计算机科学的自动控制理论中,后来被Unix系统上的编辑器ed使用,并最终发展为grep命令。最后,正则表达式被广泛使用在大多数编程语言中。

基本语法

一个正则表达式通常被称为一个模式,被用来描述、匹配一系列符合某个句法规则的字符串。正则表达式语法包括:

  • 字面值,没有任何转义,查找的对象就是其本身。比如正则表达式abc,匹配的结果就是a、b、c三个字母连在一起的字符串。
  • .,匹配除换行符外的任意字符。
  • [],中括号这种形式被称为字符类。在正则表达式中,一些字符被[]符号括住,它们表示被括号中属性约束的字符。需要注意两点:
    1. 在字符类中字符的顺序和重复性是没有意义的;
    2. .在字符类中表示的就是其本身。
  • -,为区间符号,表示在给定的范围内取值。[0123456789][0-9]是相同的,区间的范围应该是有意义的,[a-1]虽然没有语法错误,但是没有任何意义。区间左右两端对应的是字符,并不是数字,[2-41]?
  • ^,为取反符号,取反符号必须在[]中使用,取反符号是将后面的整体作为取反条件的。
  • {},为乘法集,以前面的整体作为乘法条件。乘法集区间有如下特点:
    1. 乘法集的“越长越好”属性,对于字符串aaaabb,正则表达式a{2,4}会匹配aaaa
    2. 乘法集的“全部获取”属性,对于字符串aabbaaaab,正则表达式a{2,4}会匹配aaaaaa
    3. 乘法集区间支持开区间,a{1,}是合法的。
  • ?,为判断符号,同{0,1}。当该字符紧跟在任何一个其他限制符(*,+,?{n}{n,}{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串ooooo+?将匹配单个o,而o+将匹配所有o
  • *,为通配符号,同{0,}
  • +,同{1,}
  • |,为或符号,表示或的关系,abc|edf表示匹配abc或者edf
  • (),表示组合,也可以理解为高优先级匹配。
  • \b,表示单词的边界,也就是指单词和空格间的位置。例如,er\b可以匹配never中的er,但不能匹配verb中的er
  • \B,匹配非单词边界。er\B能匹配verb中的er,但不能匹配never中的er
  • cx,匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的c字符。
  • \d,匹配一个数字字符。等价于[0-9]
  • \D,匹配一个非数字字符。等价于[^0-9]
  • \f,匹配一个换页符。等价于\x0c\cL
  • \n,匹配一个换行符。等价于\x0a\cJ
  • \r,匹配一个回车符。等价于\x0d\cM
  • \s,匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]
  • \S,匹配任何非空白字符。等价于[^ \f\n\r\t\v]
  • \t,匹配一个制表符。等价于\x09\cI
  • \v,匹配一个垂直制表符。等价于\x0b\cK
  • \w,匹配包括下划线的任何单词字符。等价于[A-Za-z0-9_]
  • \W,匹配任何非单词字符。等价于[^A-Za-z0-9_]
  • \xn,匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,\x41匹配A。正则表达式中可以使用ASCII编码。
  • ^$^表示行的开头,$表示行的结尾。
  • \,转义字符。

高(奇)级(技)语(淫)法(巧)

下面介绍的是一些正则表达式中比较生僻,但是也非常有用的用法。

  • (pattern),匹配pattern并获取这一匹配的子字符串。该子字符串用于向后引用。所获取的匹配可以从产生的Matches集合得到。
  • (?:pattern),匹配pattern但不获取匹配的子字符串,也就是说这是一个非获取匹配,不存储匹配的子字符串用于向后引用。这在使用或字符(|)来组合一个模式的各个部分是很有用。例如industr(?:y|ies)就是一个比industry|industries更简略的表达式。
  • (?=pattern)正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,Windows(?=95|98|NT|2000)能匹配Windows2000中的Windows,但不能匹配Windows3.1中的Windows。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
  • (?!pattern)正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如Windows(?!95|98|NT|2000)能匹配Windows3.1中的Windows,但不能匹配Windows2000中的Windows。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
  • (?<=pattern)反向肯定预查,与正向肯定预查类似,只是方向相反。例如,(?<=95|98|NT|2000)Windows能匹配2000Windows中的Windows,但不能匹配3.1Windows中的Windows
  • (?<!pattern)反向否定预查,与正向否定预查类似,只是方向相反。例如(?<!95|98|NT|2000)Windows能匹配3.1Windows中的Windows,但不能匹配2000Windows中的Windows

贪婪匹配和懒惰匹配

当正则表达式中包含能接受重复的限定符时,在使整个表达式能得到匹配的前提下,通常的行为是匹配尽可能多的字符。以a.*b为例,它会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,会匹配整个字符串,这被称为贪婪匹配

但是有时我们需要匹配尽可能少的字符-懒惰匹配。贪婪匹配可以转化为懒惰匹配,只需要在表达式中增加一个问号。这样.*?就意味着匹配任意数量的重复,但是在能使匹配成功的前提下使用最少的重复。a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它用于匹配aabab的话,会匹配aabab

参考资料

声明:欢迎转载,请注明出处。