一、正则表达式概念
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
正则表达式是一种数学概念,一种语法规则。不同语言引擎上实现与支持有所差异。但差异不算特别大。
二、常用元字符
元字符是一些在正则表达式中有特殊用途、不代表它本身字符意义的一组字符
元字符 |
描述 |
. |
匹配除换行符以外的任意字符 |
\w |
匹配字母、数字、下划线、汉字 |
\s |
匹配任意空白符 |
\d |
匹配数字 |
\b |
匹配单词的开始或者结束的位置 |
^ |
匹配字符串的开始 |
$ |
匹配字符串的结束 |
注意:
正则表达式中所说的“单词”是指不少于一个的连续\w
“\b” 匹配的不是字符,而是位置,精确的说法是:前一个和后一个字符不全是"\w"
三、转义
转义是为了防止特殊字符被解析,当元字符需要表达字符本身的含义的时候需要用到转义,使用 \ 。列如匹配$字符 使用\$
注意:
1、正则表达式并不是所有遇到这些特殊字符的时候都需要转义,一般在可能引起歧义或者误解的情况下需要转义,有的情况下是不需要转义的,并且转义有的时候也是无效的。
2、除了带'\'的元字符,字符组[],里面要匹配元字符转义和不转义结果都是只元字符代表的字符串本身,比如[a*b]和[a\*b],可以匹配a、*、b三个中的任何一个。
四、重复
元字符 |
描述 |
* |
重复零次或更多次 |
+ |
重复一次或更多次 |
? |
重复零次或一次 |
{n} |
重复n次 |
{n,} |
重复n次或更多次 |
{n,m} |
重复n到m次 |
注意:单独使用均是贪婪策略,匹配尽可能多的字符。
比如:abbbbb字符 a\w*b a\w+b a\w{1,}… 均是匹配 abbbbb
五、字符类
元字符 |
描述 |
[xyz] |
字符集合。匹配所包含的任意一个字符。 |
[a-z] |
字符范围。匹配指定范围内的任意字符 |
注意:除了带‘\’的元字符,‘\’,字符组[],里面要匹配元字符转义和不转义结果都是只元字符代表的字符串本身,比如[a*b]和[a\*b],可以匹配a、*、b三个中的任何一个。
六、反义元字符
元字符 |
描述 |
\W |
匹配任意不是字母、数字、下划线、汉子的字符 |
\S |
匹配任意不是空白符的字符 |
\D |
匹配任意不是数字的字符 |
\B |
匹配不是单词开头或者结束的位置 |
[^x] |
匹配排除x以外的字符 |
[^abc] |
匹配排除了abc这三个字符以外的字符 |
七、分支
分支是用于存在多种情况的匹配情况,比如要匹配 “starcor成都”或者“starcor北京”。
在小括号中使用|分割,匹配小括号中任意的一项。
starcor(成都|北京)
八、分组
使用()包含的部分为一个分组,指定成一个子表达式。
starcor(成都|北京)
九、分组
类别 |
代码/语法 |
描述 |
捕获 |
(x) |
匹配x,并捕获内容到自动命名的组里 |
(?<name>x) |
匹配x,并捕获内容到name的组里 | |
(?:x) |
匹配x,不捕获匹配的内容,也不分配组号 | |
零宽断言 |
(?=x) |
匹配x前面的位置 |
(?<=x) |
匹配x后面的位置 | |
(?!x) |
匹配后面跟的不是x的位置 | |
(?<!x) |
匹配前面不是x的位置 |
向后引用:
用于重复搜索前面某个分组匹配的文本。列如用\1来匹配分组1匹配的文本。
使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。
例如匹配:go go ,key key。这样的字符串,就要使用后向引用。正则:\b(\w+)\b\s+\1\b
这里\1 就是匹配第一个括号匹配的文本。
也可以自己为分组命名,使用(?<name>exp)或(?“name”exp),要后向引用这个分组捕获的内容时,使用 \k<name>
(?:exp)只会匹配内容,不会捕获内容,不会给分组编号
(?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。
(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。
(?!exp)零宽度负预测先行断言,断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词。
同理,我们可以用(?<!exp),零宽度负回顾后发断言来断言此位置的前面不能匹配表达式exp:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字
十、贪婪/懒惰匹配模式
贪婪匹配:在匹配过程中尽可能多的匹配字符串。
懒惰匹配:在匹配过程中尽可能少的匹配字符串。
当正则表达式中包含能够重复接受重复的限定符的时候,一般的情况都是尽可能多的匹配字符
懒惰限定符代码/语法 |
描述 |
*? |
重复任意次,但尽可能少重复 |
+? |
重复至少一次,但尽可能少重复 |
?? |
重复0次或一次,但尽可能少重复 |
{n,m}? |
重复n-m次,但尽可能少重复 |
{n,}? |
重复至少n次,但尽可能少重复 |
十一、修饰符
模式修正符 |
描述 |
i |
在和模式进行匹配的时候不区分大小写 |
m |
将字符串视为多行,默认的正则开始”^”和结束”$”将目标字符串作为单一的一行字符(通常其中包含有换行符也是如此),如果在修饰符中加上“m”,会识别换行符,开始和结束会指字符串的每一行。 |
g |
全局匹配 |
修饰符主要用于调整正则表达式,匹配模式。不同引擎支持的修饰符不同,JavaScript仅支持这3种模式
十二、JavaScript中使用正则表达式
创建正则表达式有两种方式:
直接语量法:/pattern/attributes
创建 RegExp 对象的语法:new RegExp(pattern, attributes);
参数释义:
1参数pattern是一个字符串,指定了正则表达式的模式或其他正则表达式。
2参数attributes是一个可选的模式字符串,包含属性 “g”、“i” 和 “m”,分别用于指定全局匹配、不区分大小写的匹配和多行匹配。可以多选,如“gi”。
RegExp 对象方法
方法 |
描述 |
compile |
编译正则表达式。 |
exec |
检索字符串中指定的值。返回找到的值,并确定其位置。 |
test |
检索字符串中指定的值。返回 true 或 false。 |
支持正则表达式的String对象的方法:
方法 |
描述 |
global |
RegExp 对象是否具有标志 g。 |
ignoreCase |
RegExp 对象是否具有标志 i。 |
multiline |
RegExp 对象是否具有标志 m。 |
source |
正则表达式的源文本。 |
lastIndex |
一个整数,标示开始下一次匹配的字符位置。 |
当 RegExpObject 是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。
test()同理。
注意:非全局时lastIndex不可以使用。
如果在成功地匹配了某个字符串之后就开始检索另一个新的字符串,需要手动地把这个属性设置为 0。
支持正则表达式的String对象的方法:
方法 |
描述 |
search |
检索与正则表达式相匹配的值。返回与正则表达式匹配的子串的其实位置。 没有则返回-1 |
match |
找到一个或多个正则表达式的匹配。返回个数组,如果非全局,则返回数组中第0个元素为匹配的文本,其他的为字表达式的文本;如果全局则都返回匹配文本 |
replace |
替换与正则表达式匹配的子串。 |
split |
把字符串分割为字符串数组。 |