在JavaScript中,正则表达式由RegExp对象表示。RegExp对象呢,又能够经过直接量和构造函数RegExp两种方式建立,分别以下:html
//直接量 var re = /pattern/[g | i | m];
//构造函数 var re = new RegExp(["pattern", ["g" | "i" | "m"]]);
其中,末尾的可选字符(g、i和m)分别表示:正则表达式
g: 模式执行一个全局匹配。简而言之,就是找到全部匹配,而不是在找到第一个以后就中止。数组
i: 模式执行不区分大小写的匹配。函数
m: 多行模式,^和$锚除了匹配字符串的开头和结尾外,还匹配每行的开头和结尾。例如,模式/Java$/m匹配"Java"和"Java\nScript"。测试
基础篇 |
--特殊字符--spa
在正则表达式中,全部的字母字符和数字均可以按照直接量与自身匹配,如/JavaScript/匹配的就是字符串"JavaScript",可是有些特殊字符呢?如换行符。因此在JavaScript中规定以反斜杠(\)开头的转义序列支持这些特殊字符。经常使用的特殊字符以下:code
转义字符htm |
匹配对象 |
\nblog |
换行符 |
\r |
回车 |
\f |
换页符 |
\t |
制表符 |
\v |
垂直制表符 |
--字符类--
在正则表达式中,假若将单独的字符放入方括号([ ])中,就能够组合成字符类。应用到匹配字符串中,咱们能够将其当作一个漏斗,当字符串中的每一个字符经过它时,都查找是否在这个类里面,如若在,就匹配成功,不然out。以下:
/* match为字符串的方法,它的惟一参数就是一个正则表达式, 若是该正则表达式设置了标志g,该方法返回的数组包含的就是出如今字符串中的全部匹配。 详细的用法将在下面“正则表达式在String中的应用”细讲 */ "abc".match(/[abc]/g);
匹配结果为:
若是咱们的意愿是,想匹配除字符a、b、c以外的字符呢?咱们能够定义一个否认类,只需将^符号放入[ ]中做为开头就OK啦。以下:
"abc".match(/[^abc]/g);
因为某些字符类常常用到,固JavaScript的正则表达式就用反斜杠(\)与一些特殊字符组合起来表示这些经常使用类,而没必要再须要咱们自行添加,如\d。
经常使用正则字符类以下:
字符类 |
匹配 |
例子 |
[ …] |
位于方括号之中的任意字符 |
/M[onke]y/ 匹配 "Moy" |
[ ^…] |
除包含在方括号之中的任意字符 |
/M[^onke]y/ 匹配 "May" |
. |
除换行符以外的任意字符 |
/../ 匹配 "Mo" |
\w |
字母、数字或下划线 |
/1\w/ 匹配 "1A" |
\W |
除字母、数字和下划线以外的字符 |
/1\W/ 匹配 "1%" |
\s |
单个空白字符 |
/M\sK/ 匹配 "M K" |
\S |
单个非空白字符 |
/M\SK/ 匹配 "M_K" |
\d |
0到9的数字 |
/\d/ 匹配 "1" |
\D |
非数字 |
/\D/ 匹配 "M" |
--重复匹配--
当咱们须要匹配三位数字时,咱们能够这样:/\d\d\d/,可是当咱们须要匹配10位或者更多时呢?考虑到这一点,正则表达式为咱们提供了重复字符{ n, m },表示匹配前一项至少n次,可是不能超过m次。例如,刚才咱们所说的匹配三位数字时,咱们能够利用重复字符这样啦:/\d{3}/。
因为某些重复类型常常用到,so,正则规定一些特殊字符表示这些重复类型。
正则重复字符,详情见下:
字符 |
含义 |
例子 |
{n, m} |
匹配前一项至少n次,但不能超过m次 |
/\d{2,3}/ 匹配"12" |
{n, } |
匹配前一项至少n次,或者更多 |
/\d{2, }/ 匹配"123" |
{n} |
匹配前一项刚好n次 |
/\d{2}/ 匹配"12" |
? |
匹配前一项0次或者1次,等价于{0,1} |
/\d?/ 匹配"2" |
+ |
匹配前一项1次或者屡次,等价于{1, } |
/\d+/ 匹配"12" |
* |
匹配前一项0次或者屡次,等价于{0, } |
/\d*/ 匹配"12" |
另,以上重复字符重复规则为:尽量多的匹配,即俗称的“贪婪匹配”,如:"aaaa".match(/a+/);匹配的就是整个字符串"aaaa",而不是匹配到第一个字符a时,就放弃匹配。
那么,有所谓的"贪婪匹配",就有"非贪婪匹配",它的规则嘛,确定与"贪婪匹配"相反咯,即:尽量少的匹配。
那么,怎么才能触发非贪婪模式呢?
只须要在重复字符后加入?,就ok啦,如({1, 4}?、+?等),如"aaaa".match(/a+?/);就只会匹配首个字符a咯。
注意,是尽量少的匹配,而不是少的匹配哦。
神马意思?以下:
"aaab".match(/a*b/);
"aaab".match(/a*?b/);
!匹配结果都是"aaab"!
有没有点诧异,为何"aaab".match(/a*?b/);的匹配结果会是"aaab",而不是"ab"呢?
那是由于正则匹配都是从左往右的,就"aaab".match(/a*?b/);而言,当遇到首字符a时,它会继续往下匹配,直到能符合匹配模式/a*?b/为止,这就是为何说是尽量少的匹配,前提是知足匹配规则。
如"abbb".match(/ab*?/)的匹配结果就是"a"啦。
--字符 |、( )、(?: …)--
1.一、字符" | " 用于分隔,表示或。
什么意思?
举个栗子,如/ab | cd | ef/就能够匹配字符串"ab"或者"cd"或者"ef"。
是否是和字符类[ ]很像啊?
是的,如/a | b | c/和/[abc]/匹配效果是同样的哦。
But,字符类[ ]仅针对单个字符而言,而分隔字符" | "涉及更广,能够针对多个字符而言,如上述所说的/ab | cd | ef/,字符类就不行咯。
你可能会说,若是我想对利用" | "组装的类进行屡次匹配呢?
加个括号就是啦。如:
/(ab | cd |ef)+/
好滴,说到括号,咱们再来看看它的做用。很是强大哦。
1.二、括号"( )"
括号的做用以下:
一、咱们能够将一个单独的项目组合成一个子表达式,以便咱们能够用|、*等来处理它。如,上诉所示的/(ab | cd | ef)+/。
二、利用括号括起来的部分,咱们能够在正则表达式的后面引用前面用括号括起来的子表达式的匹配结果,注意是结果,而不是括起来的正则表达式。
针对第二点,有什么用呢?如咱们有个需求,我想匹配在单引号或者双引号中的数字(’12345’)时,咱们就可垂手可得利用这第二点,写好正则表达式,以下:
/(['"])\d*\1/
测试结果以下:
好了,就第二点做用而言,结合上述demo,咱们再来看看它的具体引用法则吧:
----以反斜杠\加数字的方式,引用前面带括号的子表达式,而这个数字呢指的就是第几个子表达式,计算规则为从左往右,计算遇到的左括号" ( ",到想引用的地方位置为止,不管在括号中还嵌套不嵌套括号。
测试Demo以下:
咦,假若我只想让括号的做用为分组,而不想在后面计入引用呢?毕竟括号多了,很差计算呢。
那么,咱们就来看看字符(?: …)咯。
1.三、(?: …)
(?: …)的做用就是,规定括号只用于分组,而不计入后面的引用,很差理解,看个demo就明白啦。以下:
/(Java(?:Script))(nice)/
若是我想在末尾引用子表达式nice,那么是\2,而不是\3咯,由于用(?: …)来分组滴,只管分组,而不引用,切记切记。
对(?: …)的测试demo以下:
--匹配位置--
在前面咱们提到,建立正则对象时,可选字符m表示:多行模式,^和$锚除了匹配字符串的开头和结尾外,还匹配每行的开头和结尾。
那么这个^和$就是正则为咱们提供的匹配位置,即所谓的锚。
例如:
将/JavaScript/变为/^JavaScript/,就只匹配字符串中开头为JavaScript的啦,如匹配"JavaScriptxxx"中的JavaScript,而不匹配"xxxJavaScript"中的JavaScript。
正则表达式中的锚字符详情见下:
字符 |
含义 |
^ |
匹配字符串的开头 |
$ |
匹配字符串的结尾 |
\b |
匹配一个词语的边界,指[a-zA-Z_0-9]以外的字符 |
\B |
匹配非词语边界位置 |
(? = p) |
正前向声明,exp1(?=exp2),匹配后面是exp2的exp1 |
(? ! p) |
反前向声明,exp1(?!exp2),匹配后面不是exp2的exp1 |
^和$好理解,可是\b、(?=)、(?!)可能比较陌生,结合上表,咱们再来看看下面的demo就好啦。
对于\b的Demo以下:
对于(? = p)的Demo以下:
对于(? ! p)的Demo以下:
哎,本想一鼓作气,没想到写完基础篇发现已经这么晚了。。。有时间再梳理下正则表达式在JavaScript中的应用吧。
具体应用,见"理清JavaScript正则表达式--下篇"
晚安,everyone~