正则表达式快速入门

提醒:本文发布于 2662 天前,文章内容可能 因技术时效性过期 或 被重新修改,请谨慎参考。

TOC
  1. 1. 元字符
  2. 2. 例子
  3. 3. 字符转意
  4. 4. 重复
  5. 5. 字符类
  6. 6. 分枝条件
  7. 7. 分组
  8. 8. 反义
  9. 9. 后向引用
  10. 10. 零宽断言
  11. 11. 负向零宽断言
  12. 12. 注释
  13. 13. 贪婪与懒惰

元字符

元字符是功能性的匹配符号, 如:
\b 单词的开头或结尾,也就是单词的分界处
* 匹配任意数量的字符
. 匹配除了换行之外的所有字符
\d 匹配0到9单个数字
\s 匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等
\w匹配 字母 或 数字 或 下划线 或 汉字 等
^ 匹配字符串的开始
$ 匹配字符串的结束

例子

\ba\w*\b 匹配以字母a开头的单词——先是某个单词开始处(\b),然后是字母a,然后是任意数量的字母或数字(\w),最后是单词结束处(\b)
0\d\d-\d\d\d\d\d\d\d\d匹配这样的字符串:以0开头,然后是两个数字,然后是一个连字号“-”,最后是8个数字, 简写成0\d{2}-\d{8} , {}是限定符
^\d{5,12}$ QQ号必须为5位到12位数字 {5,12}表示次数不能少于5次,不能多于12次
\d+匹配1个或更多连续的数字。这里的+是和`
类似的元字符,不同的是*匹配重复任意次(可能是0次),而+则匹配重复1次或更多次\b\w{6}\b` 匹配刚好6个字符的单词。

字符转意

查找元字符本身的话,比如你查找.,或者*,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使用\来取消这些字符的特殊意义。因此,你应该使用\.\*。当然,要查找\本身,你也得用\\

重复

符号 表示
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

字符类

[ ] 集合查找 ,比如 [abcde] 表示匹配里面包含的字符 , 常见的[0-9]\d等价, 即匹配一位数字, [a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)
\(?0\d{2}[) -]?\d{8}首先是一个转义字符\(,它能出现0次或1次?,然后是一个0,后面跟着2个数字\d{2},然后是)-空格中的一个,它出现0次或1次?,最后是8个数字\d{8}

分枝条件

上面那个表达式也能匹配010)12345678或(022-87654321这样的“不正确”的格式。
正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开。
0\d{2}-\d{8}|0\d{3}-\d{7}表示0开头接两位数字,-后面连着8位数的电话号码,比如020-12345678 或者 0开头接三位数字,-后面连着7位数的电话号码,比如0751-1234567
使用分枝条件时,要注意各个条件的顺序。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。

分组

如果想要重复多个字符又,你可以用小括号来指定子表达式(也叫做分组)
(\d{1,3}\.){3}\d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字,(\d{1,3}\.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})
正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的IP地址:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)

反义

有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义:

符号 表示
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[ ^x ] 匹配除了x以外的任意字符
[ ^aeiou ] 匹配除了aeiou这几个字母以外的任意字符

例子:
\S+匹配不包含空白符的字符串。
<a[^>]+>匹配用尖括号括起来的以a开头的字符串

后向引用

待学习

零宽断言

待学习

负向零宽断言

待学习

注释

待学习

贪婪与懒惰

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)
为什么第一个匹配是aab(第一到第三个字符)而不是ab(第二到第三个字符)?简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权

符号 表示
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复

参考: http://deerchao.net/tutorials/regex/regex.htm

访客评论