js 正则表达式
一.正则表达式的多种字符类型
1.普通字符
字母、汉字、数字、下划线以及没有特殊意义的标点符号
2.转义字符
有许多字符在正则表达式中有特殊的意义,因此需要在它的前面加上"\"来代表字符本身
例如"^"、"$"、"/",若要匹配他们,得写成: "\^"、"\$"、"\/"
3.特殊字符
3.1 能够与多种字符匹配的字符
\d (digit)能匹配任意数字
\D 能匹配所有非数字,相当于[^0-9]
\w 能匹配字母(大小写)数字和下划线
\s (space) 能匹配空白字符,包括换行符\n、回车符\r、空格 、制表符\t等
\S 非空白字符
. 能匹配除了\n以外的一切
3.2 自定义能匹配多种字符的表达式
[] 或 例如[abc],匹配a或b或c
[^] 除xxx之外 例如[^abc],匹配除abc之外的字符
[-] 至 例如[a-f],匹配a值f之间的任一个字符 ,包括a与f
3.3 修饰匹配次数
{n} 重复n次数 例如: /a{2}/,相当于/aa/
{m, n} 重复m-n次 例如/\w{2, 4}/,相当于 /\w\w/
{m,} 重复至少m次 例如/ca{2,}/,可以匹配"caca", "12cacaca"
? 匹配0次或1次 例如/a[bc]?/,可以匹配"a"、"ab"、"ac"
相当于{0,1}
+ 至少匹配1次 例如/[abc]+e/,可以匹配"ae"、"abce"、"dce"
* 匹配0次或任意次 ,相当于{0,}
3.4 一些抽象意义的特殊字符
^ 与字符串开始的地方匹配
$ 与字符串结束的地方匹配
\b 匹配单词的边界,例如 /\dgood/可以匹配"goodsss"、"are good"、"are,good"
| 字符串层面上的或,例如/we|are|good/可以匹配"weghj"、"areghj"、"goodbgnhm"
() 1.在修饰匹配次数时可作为整体被使用,例如/a(bc)?/在没有()时匹配"abc",又()时匹配"a"和"abc"
2.在取匹配结果时,括号内的内容可以被单独取到 例如:/¥(\d+\.?\d*)/.exec('¥20.4') //["¥20.4", "20.4", index: 0, input: "¥20.4"]
可以看出"20.4"被单独取出
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
二.正则表达式的一些高级规则:
贪婪模式与非贪婪模式
贪婪模式
在使用修饰匹配次数的特殊符号时,有多种方法能使表达式匹配不同次数,如: {m, n}、{m,}、+等,这种匹配不定次数的表达式在匹配过程中,总是尽可能多地匹配,例如"dxxxdxxxd"
(d)(\w+) 匹配结果为 "dxxxdxxxd",它可以匹配"dx"、"dxx"...但基于此原则,尽可能多地匹配
(d)(\w+x) 匹配结果为"dxxxdxxx" ,在遵守此原则的同时得保证正则表达式的成立
非贪婪模式
在修饰匹配次数的特殊符号后再加上一个 "?" 号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 "不匹配"。这种匹配原则叫作 "非贪婪" 模式,也叫作 "勉强" 模式。
如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。
(d)(\w+?) 匹配结果为 "dx"
(d)(\w+?x) 匹配结果为"dxx"
反向引用
介绍反向引用之前得介绍些基本概念
捕获组:
捕获组就是将正则表达式中子表达式中匹配的内容存入内存中以编号排列的组里,方便后面的引用,具体解释可参考:
http://blog.csdn.net/lxcnn/article/details/4146148
捕获组按照从左到右、由外到内的顺序排列
例如:/(\d{4})- ((\d{2})-(\d\d))/
(\d{4}) 匹配的内容在捕获组1
((\d{2})-(\d\d)) 匹配的内容在捕获组2
(\d{2}) 匹配的内容在捕获组3
(\d\d) 匹配的内容在捕获组4
反向引用
捕获组捕获到的内容,不仅可以在正则表达式外部通过程序进行引用,也可以在正则表达式内部进行引用,这种引用方式就是反向引用
语法:普通捕获组反向引用:\k<number>,通常简写为\number
例如:正则表达式:([ab])\1
对于正则表达式“([ab])\1”,捕获组中的子表达式“[ab]”虽然可以匹配“a”或者“b”,但是捕获组一旦匹配成功,反向引用的内容也就确定了。如果捕获组匹配到“a”,那么反向引用也就只能匹配“a”,同理,如果捕获组匹配到的是“b”,那么反向引用也就只能匹配“b”。由于后面反向引用“\1”的限制,要求必须是两个相同的字符,在这里也就是“aa”或者“bb”才能匹配成功。
考察一下这个正则表达式的匹配过程,在位置0处,由“([ab])”匹配“a”成功,将捕获的内容保存在编号为1的组中,然后把控制权交给“\1”,由于此时捕获组已记录了捕获内容为“a”,“\1”也就确定只有匹配到“a”才能匹配成功,这里显然不满足,“\1”匹配失败,由于没有可供回溯的状态,整个表达式在位置0处匹配失败。
正则引擎向前传动,在位置5之前,“([ab])”一直匹配失败。传动到位置5处时,,“([ab])”匹配到“b”,匹配成功,将捕获的内容保存在编号为1的组中,然后把控制权交给“\1”,由于此时捕获组已记录了捕获内容为“b”,“\1”也就确定只有匹配到“b”才能匹配成功,满足条件,“\1”匹配成功,整个表达式匹配成功,匹配结果为“bb”,匹配开始位置为5,结束位置为7。
扩展一下,正则表达式“([a-z])\1{2}”也就表达连续三个相同的小写字母。
接下来介绍一个网上流行的例子
正则表达式/<(\w+)\s*(\w+(=('|").*?)\4)?\s*)*>.*?<\/\1>/在匹配"<td id='td1' style='color:while'></td>"时成功匹配。这里的反向引用\1等于(\w+),从而保证了只有当"<td>"与"<
\td>"配对时,模式匹配才成功,否则匹配失败:而\4等于"'|"",保证"="号后要以单引号"'"或者双引号"""开始,并以对应的符号结尾,如id='td1',不允许出现id=id='td1'的情况。