在我看来,正则表达式最主要的作用就是匹配字符串,可以用来验证表单的输入等功能。不了解正则表达式的或者想详细学学正则表达式的可以参考这篇文章教学:http://deerchao.net/tutorials/regex/regex.htm。
JS通过RegExp类型来支持正则表达式,其创建正则表达式的方式有两种:
1.字面量形式定义:
var expression = /pattern/flags;
2.使用RegExp构造函数:
var pattern = new RegExp("pattern","flags");
pattern就是标准的正则表达式,后面的flags是标志,用以标志正则表达式的匹配模式。有3种标志:
1.g:表示全局模式,表示该模式应用于整个字符串,不会因为匹配到了一个就停下来了,后面会讲到有一个属性会记录pattern匹配的字符串的位置,g模式下,该位置会不断改变。
2.i:表示不区分大小写模式,在匹配时忽略模式和字符串的大小写。
3.m:表示多行模式,即匹配完一行还会继续匹配下一行。
这些flags可以搭配使用,增强功能。注意正则表达式中也有那种特殊字符,如果要匹配这些字符,需要转义,这些字符如下:
( ) [ ] \ ^ $ | ? . * + { }
转义很简单,在这些字符前面加上反斜杠\即可。如:
//匹配"ab"
var pattern1 = /ab/g;
//匹配"[ab]"
var pattern2 = /\[ab\]/g;
上面说到两种方式创建正则表达式。两者区别如下:
1.字面量方式直接写标准正则即可,而使用RegExp构造函数方式创建要求传入的第一个参数如果正则里面有反斜杠\,必须写双倍反斜杠\。
var pattern = /\w\[ab\]/i;
var pattern2 = new RegExp("\\w\\[ab\\]","i");
//pattern 和pattern2等价,如果没有\,则两者里面的正则一样
2.字面量方式创建的正则表达式共享一个RegExp实例,而另一种方式创建的会创建一个产生一个实例,new方式很容易理解。
注意两种方式创建的正则表达式都是一个RegExp实例,而不是第一种创建的就不是RegExp实例了。
RegExp的每个实例都有一些属性,来获得模式的各种信息,如下:
- global:boolean,表示是否设置了g
- ignoreCase:boolean,表示是否设置了i
- multiline:boolean,表示是否设置了m
- lastIndex:整数,表示开始搜索下一个字符要从字符串的何处开始,从0开始
- source:正则表达式的字符串表示,和字面量创建的正则一样,不包含标志位纯标准正则的字符串表示。注意如果是new 出的pattern这个属性值和传入的第一个参数可能会不同,因为可能会有\,反正一切以标准正则为准就对了。
RegExp的方法主要是exec(String arg),接收一个String参数,即要匹配的字符串。返回包含第一个匹配项信息的数组;没有批评返回null.其包含两个额外属性:index和input。index表示匹配性在字符串中的位置,input表示要匹配的字符串。在返回的数组中,第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串,匹配成功多少个捕获组,后面就还有多少个元素。不知道捕获组是什么的参考开头给出的那篇文章。例如:
var text = "mom and dad and baby";
var pattern = /mom( and dad( and baby))/gi;
var match = pattern.exec(text);
console.log(match);
/*[ 'mom and dad and baby',
' and dad and baby',
' and baby',
index: 0,
input: 'mom and dad and baby' ]*///注意index和input是属性不是元素
console.log(match.index);//0开头就匹配到了
console.log(match.input);//"mom and dad and baby"
console.log(match[0]);//"mom and dad and baby"
console.log(match[1]);//"and dad and baby"第一个捕获组捕获(可以理解为一个括号一个捕获组)
console.log(match[2]);//"and baby"第二个捕获组捕获
注意exec每次调用都只返回一个匹配项,捕获组不算。设置了g标志,如果有多个匹配项,每次调用exec,lastIndex会变,表示下次应该从哪个下标开始匹配。如果没有设置g,每次都重新匹配,从0开始。
第二个方法为test,也是比较常用方法。接收一个字符串参数。若成功匹配,返回true。适用于不需要知道字符串内容,指向判断字符串满不满足格式的情况,常用于表单输入的验证。
还有要注意的是RegExp方法toString()/toLocalString()/valueOf(),这三个方法返回的是一样的都是带标志位的正则表达式,即字面量正则表达式的完整形式。如"/\wab/g"。而其source属性的值是纯粹的正则表达式,如"\wab".
还有一部分是关于RegExp对象的属性,这些属性适用于作用域中的所有正则表达式,并且会基于所执行的最近一次正则表达式操作而变化。有两种方式访问,长属性和短属性。例如:
var str = "this has been a short summer";
var pattern2 = /(.)hort/g;
if(pattern2.test(str)) {//匹配此作用域的正则匹配结果
console.log(RegExp.input);//this has been a short summer
console.log(RegExp.lastMatch);//short最近一次的匹配项
console.log(RegExp.lastParen);//s最近一次的捕获组
console.log(RegExp.leftContext);//this has been a最近一次匹配项左边的字符串
console.log(RegExp.rightContext);// summer最近一次匹配项右边的字符串
}
除了上面几个属性外,还有多达9个用于存储捕获组的属性。RegExp.$1,访问第一个捕获组内容,以此类推,最多9个。在调用exec()或者test()方法时会自动填充这些属性。