首页 > 代码库 > 正则表达式
正则表达式
直接量语法
/pattern/attributes
创建 RegExp 对象的语法:
new RegExp(pattern, attributes);
一、attributes
修饰符 |
描述 |
例子 |
i |
执行对大小写不敏感的匹配。 |
var str="Visit W3School"; Visit W3School |
g |
执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。若不含g,则默认找到第一个匹配后停止 |
var str="Is this all there is?"; Is this all there is? |
m |
执行多行匹配。 |
|
二、pattern
1. 方括号:查找某个范围的字符
表达式 |
描述 |
例子 |
[abc] |
查找方括号之间的任何字符。方括号内是"或"的关系 |
var str="Is this all there is?"; Is this all there is? |
[^abc] |
查找任何不在方括号之间的字符。 |
var str="Is this all there is?"; Is this all there is? |
[0-9] |
查找任何从 0 至 9 的数字。 |
|
[a-z] |
查找任何从小写 a 到小写 z 的字符。 |
|
[A-Z] |
查找任何从大写 A 到大写 Z 的字符。 |
|
[A-z] |
查找任何从大写 A 到小写 z 的字符。 |
|
[adgk] |
查找给定集合内的任何字符。 |
|
[^adgk] |
查找给定集合外的任何字符。 |
|
(red|blue|green) |
查找任何指定的选项。 |
|
2. 元字符:拥有特殊含义的字符
元字符 |
描述 |
例子 |
. |
查找单个字符,除了换行和行结束符。 |
var str="That‘s hot!"; That‘s hot! |
\w |
查找单词字符。(单词字符包括:a-z、A-Z、0-9,以及下划线。) |
var str="Give 100%!"; Give 100%! |
\W |
查找非单词字符。 |
var str="Give 100%!"; Give 100%! |
\d |
查找数字。 |
var str="Give 100%!"; Give 100%! |
\D |
查找非数字字符。 |
var str="Give 100%!"; Give 100%! |
\s |
查找空白字符。 |
var str="Is this all there is?"; Is this all there is? |
\S |
查找非空白字符。 |
var str="Is this all there is?"; Is this all there is? |
\b |
匹配单词边界。 |
var str="Visit W3School"; Visit W3School |
\B |
匹配非单词边界。 |
var str="Visit W3School"; |
\0 |
查找 NUL 字符。 |
|
\n |
查找换行符。 |
var str="Visit W3School.\nLearn Javascript."; Visit W3School.\nLearn Javascript. |
\f |
查找换页符。 |
|
\r |
查找回车符。 |
|
\t |
查找制表符。 |
|
\v |
查找垂直制表符。 |
|
\xxx |
查找以八进制数 xxx 规定的字符。 |
var str="Visit W3School. Hello World!"; Visit W3School. Hello World! |
\xdd |
查找以十六进制数 dd 规定的字符。 |
var str="Visit W3School. Hello World!"; Visit W3School. Hello World! |
\uxxxx |
查找以十六进制数 xxxx 规定的 Unicode 字符。 |
var str="Visit W3School. Hello World!"; Visit W3School. Hello World! |
-
\b
匹配的单词边界并不包含在匹配中,即匹配的单词边界的长度为零
例:
/\bm/ 匹配 "moon" 中的 ‘m‘;
/oo\b/ 不匹配 "moon" 中的 ‘oo‘,因为 ‘oo‘ 后面的 ‘n‘ 是一个单词字符;
/oon\b/ 匹配 "moon" 中的 ‘oon‘,因为 ‘oon‘ 位于字符串的末端,后面没有单词字符;
/\w\b\w/ 不匹配任何字符,因为单词字符之后绝不会同时紧跟着单词边界 和单词字符。
-
\B
匹配位置的上一个和下一个字符的类型是相同的:即必须同时是单词,或必须同时是非单词字符。字符串的开头和结尾处被视为非单词字符。
匹配位置的长度为0
例:
/\B../ 匹配 "noonday" 中的 ‘oo‘,‘nd‘,‘ay‘(\B的位置在n和o之间,左边n,右边o,都是单词字符)
/y\B./ 匹配 "possibly yesterday." 中的 ‘ye‘。
3. 量词
量词 |
描述 |
例子 |
n+ |
匹配任何包含至少一个 n 的字符串。 |
var str="Hellooo World! Hello W3School!"; Hellooo World! Hello W3School! |
n* |
匹配任何包含零个或多个 n 的字符串。 |
var str="Hellooo World! Hello W3School!"; Hellooo World! Hello W3School!(l,looo,l,l,lo,l)
|
n? |
匹配任何包含零个或一个 n 的字符串。 (区别:n+ 一个或多个,n* 零个或多个,n? 零个或一个) |
var str="1, 100 or 1000?"; 1, 100 or 1000? |
n{X} |
匹配包含 X 个 n 的序列的字符串。 |
var str="100, 1000 or 10000?"; 100, 1000 or 10000? |
n{X,Y} |
匹配包含 X 或 Y 个 n 的序列的字符串。 |
var str="100, 1000 or 10000?"; 100, 1000 or 10000? |
n{X,} |
匹配包含至少 X 个 n 的序列的字符串。 |
var str="100, 1000 or 10000?"; 100, 1000 or 10000? |
n$ |
匹配任何结尾为 n 的字符串。 |
var str="Is this his"; Is this his |
^n |
匹配任何开头为 n 的字符串。 |
var str="Is this his"; Is this his |
?=n |
匹配任何其后紧接指定字符串 n 的字符串。 |
var str="Is this all there is"; Is this all there is |
?!n |
匹配任何其后没有紧接指定字符串 n 的字符串。 |
var str="Is this all there is"; Is this all there is |
匹配……的字符串:只要整个字符串中有匹配的字符,不管匹配位置在哪,都算匹配成功。即test方法返回true
-
n+
-
例1:
/o/g匹配"Hellooo World!"中的o,o,o,o
/o+/g匹配"Hellooo World!"中的ooo,o
-
例2:
/lo/g匹配"Hellooo World! Hello W3School!"中的lo,lo
/lo+/g匹配"Hellooo World! Hello W3School!"中的looo,lo(lo+匹配一个1后面跟一个或多个o)
/(lo)+/g匹配"Hellololo World! Hello W3School!"中的lololo,lo((lo)+匹配一个或多个lo的组合)
-
例3:
/\w/g匹配"Hellooo World!"中的H,e,l,l,o,o,o,W,o,r,l,d
/\w+/g匹配"Hellooo World!"中的Hellooo,World
-
-
-
贪婪模式
在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:"{m,n}", "{m,}", "?", "*", "+",具体匹配的次数随被匹配的字符串而定。这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。
例1:
表达式 "<td>(.*)</td>" 与字符串 "<td><p>aa</p></td><td><p>bb</p></td>" 匹配。
例2:
针对文本 "dxxxdxxxd"
-
表达式 |
匹配结果 |
(d)(\w+) |
"\w+" 将匹配"dxxxdxxxd" |
(d)(\w?) |
整个将匹配"dxxxdxxxd" |
(d)(\w+)(d) |
"\w+" 将匹配"dxxxdxxxd" 虽然 "\w+" 也能够匹配上最后一个 "d",但是为了使整个表达式匹配成功, "\w+" 需要 "让出" 最后一个 "d" |
由此可见,"\w+" 在匹配的时候,总是尽可能多的匹配符合它规则的字符。
虽然第二个举例中,它没有匹配最后一个 "d",但那也是为了让整个表达式能够匹配成功。
同理,带 "*" 和 "{m,n}" 的表达式都是尽可能地多匹配,带 "?" 的表达式在可匹配(1)可不匹配(0)的时候,也是尽可能的 "要匹配"。这种匹配原则就叫作 "贪婪" 模式 。
-
-
非贪婪模式
在修饰匹配次数的特殊符号后再加上一个 "?" 号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 "不匹配"。
(区分:此处"?"与量词"?"不同,量词"?"是修饰匹配次数的特殊符号,此处"?"是非贪婪模式的专用符号)
这种匹配原则叫作 "非贪婪" 模式,也叫作 "勉强" 模式。如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再勉强匹配一些,以使整个表达式匹配成功。
例1:
表达式 "<td>(.*?)</td>" 与字符串 "<td><p>aa</p></td><td><p>bb</p></td>" 匹配。
例2:
针对文本 "dxxxdxxxd"
-
表达式 |
匹配结果 |
(d)(\w+?) |
"\w+?" 将匹配"dxxxdxxxd" |
(d)(\w??) |
整个将匹配"dxxxdxxxd" |
(d)(\w+?)(d) |
"\w+?" 将匹配"dxxxdxxxd" 为了让整个表达式匹配成功,"\w+?" 不得不匹配 "xxx" 才可以让后边的 "d" 匹配。 |
-
- 捕获组:用元字符()表示,小括号包含的表达式所匹配到的字符串可以通过RegExp的构造函数属性单独获取
-
反向引用:
- 小括号包含的表达式所匹配到的字符串不仅是在匹配结束后才可以使用,在匹配过程中也可以使用,表达式后边的部分,可以引用前面小括号内的子匹配已经匹配到的字符串。
- 引用方法是 "/" 加上一个数字。"/1" 引用第1对括号内匹配到的字符串,"/2" 引用第2对括号内匹配到的字符串……以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号 "(" 在前,那这一对就先排序号。
-
例子:
-
例1:表达式 /(‘|")(.*?)(/1)/
匹配模式说明:
第一个捕获组表示匹配一个单引号或双引号,
第二个捕获组表示匹配任意一个字符至少0个,问号表示的是采用非贪婪模式,
第三个捕获组表示反向引用第一个捕获组,即匹配一个单引号或双引号
在匹配 "‘Hello‘, \"World\"" 时(需将内部双引号转义),匹配结果是:成功;
匹配到的内容是:‘Hello‘。再次匹配下一个时,可以匹配到 "World"。
-
-
例2:表达式 /(\w)\1{4,}/
匹配模式说明:
第一个捕获组表示匹配一个单词字符,然后使用\1反向引用第一个捕获组,同样表示匹配一个单词字符,
又通过后面的数量{4,},约束至少4个,
整个匹配模式就是匹配第一个单词字符+后面4个单词字符,至少5个单词字符,如果存在则成功。
在匹配 "aa bbbb abcdefg ccccc 111121111 999999999" 时,匹配结果是:成功;匹配到的内容是 "ccccc","999999999"。
-
例3:表达式 /<(\w+)\s*(\w+(=(‘|").*?\4)?\s*)*>.*?<\/\1>/
匹配模式说明:
表达式中有4个捕获组:(\w+)、(\w+(=(‘|").*?\4)?\s*)、(=(‘|").*?\4)、(‘|"),
反向引用使用了两次,第一次反向引用捕获组4,第二次反向引用捕获组1,
整个模式含义:
1、匹配一个左尖括号
2、第一个捕获组,匹配单词字符1到多个
3、匹配空白字符,0到多个
4、进入第二个捕获组,先匹配单词字符1到多个
5、进入第三个捕获组,先匹配一个=号
6、进入第四个捕获组,匹配一个单引号或一个双引号
7、然后第三个捕获组继续匹配,匹配任意字符0到多个,采用非贪婪模式,尽量少匹配
8、然后反向引用第四个捕获组的结果,即执行第6步的结果
9、回到第二个捕获组继续匹配,?表示第三个捕获组匹配的结果个数为0或1个,然后再匹配一个空白字符0到多个
10、第二个捕获组匹配的结果个数为0到多个
11、然后匹配一个右尖括号,后面是一个任意字符个数为0到多个,采用非贪婪模式,尽量少匹配,再后面是一个左尖括号和正斜杠
12、正斜杠后面反向引用第一个捕获组的结果,即执行第二步的结果
13、最后是一个右尖括号
在匹配 "<td id=‘td1‘ style=\"bgcolor:white\"></td>" (字符串中,双引号需转义,和正则表达式无关)时,匹配结果是成功。
如果 "<td>" 与 "</td>" 不配对,则会匹配失败;如果改成其他配对,也可以匹配成功。
-
例4:匹配一个带有class=parent的div
var str = "<div id=\"parent\" class=\"parent0 parent parent1\" style=\"bgcolor:white\"><div><div></div></div><div></div></div>";
var patt = /<(\w+)\s*(\w+(=(‘|").*?\4)?\s*)*(class=(‘|").*?parent.*?\6\s*)(\w+(=(‘|").*?\9)?\s*)*>.*<\/\1>/g;
var result;
while ((result = patt.exec(str)) != null) {
console.log(result[0]);
}
结果:
<div id="parent" class="parent0 parent parent1" style="bgcolor:white"><div><div></div></div><div></div></div>
此方法缺点:如果div parent外层还有一个div grandpa,那最后匹配到的</div>是grandpa的,而非parent的
正则表达式