RegExp
创建正则表达式的两种方式
字面量
var expression = /pattern/flags
pattern : 正则表达式
flags : 匹配模式,有3个取值。g:全局模式,表示不在发现第一个匹配项之后就停止,而是应用于所有字符串。i:不区分大小写模式。m:多行模式,到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项。
RegExp构造函数
var pattern = new RegExp(“正则表达式”,”g/i/m”);
两种方式创建的是完全等价的两个正则表达式。
但是要注意,有两点不同的,一点是因为传入构造函数中的是字符串参数,所以某些情况下要对字符进行双重转义。所有元字符必须双重转义,已经转义过的字符也要如此。如/\ [bc\]at/,与之等价的字符串为”\\ [ bc\\]at”。还有一点特别的是,在ECMAScript3中,字面量方式的正则表达式始终会共享一个RegExp实例,而使用构造函数的则每次都是一个新实例。
var re = null,i;
for(i=0;i<10;i++){
re = /cat/g;
re.test("catastrophe");
}
for(i=0;i<10;i++){
re = new RegExp("cat","g");
re.test("catastrophe");
}
由于RegExp的实例属性不会被重置所以在第一个循坏中再次调用test方法会失败。但是ES5已经对此做出了规定,使用字面量也必须像构造函数一样创建新的实例,IE9+,FF4+,Chrome都做出了修正。
实例属性
属性 | 说明 |
---|---|
global | 布尔值,是否设置了g标志 |
ignoreCase | 布尔值,是否设置了i标志 |
multiline | 布尔值,是否设置了m标志 |
lastIndex | 整数,表示开始搜索下一个匹配项的位置,从0开始 |
source | 表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回 |
实例方法
exec()
直接看代码
var text = "mom and dad and baby";
var pattern = /mom( and dad (and baby)?)?/gi;
var matches = pattern.exec(text);
alert(matches.index); //0
alert(matches.input); //mom and dad and baby
alert(matches[0]); //mom and dad and baby
alert(matches[1]); //and dad and baby
alert(matches[2]); //and baby
该方法返回的数组,包含两个额外的属性,index和input
index–匹配项在字符串中的位置
input–匹配的字符串
返回的数组第一项存着与整个模式匹配的字符串,之后依次存储与模式中的捕获组匹配的字符串
对于该方法来说,即使设置了g标志,每次也只会返回一个匹配项,但是每次调用exec都会在字符串中继续查找,而若是不设置g标志,每次调用也只会从头开始查找。换句话说,就是lastIndex变不变的问题。设置了g标志,该值会依次变化,否则每次都是0。
IE的js实现,即使是非g模式下,lastIndex属性每次也会变化。
test()
返回一个布尔值,匹配则true,否则false。
在只想知道字符串是否匹配而不需要知道其文本内容时,这是很有效的。
构造函数属性
属性 | 说明 |
---|---|
input | 最近一次要匹配的字符串 |
lastMatch | 最近一次的匹配项 |
lastParen | 最近一次匹配的捕获组 |
leftContext | input字符串中lastMatch之前的文本 |
multiline | 是否所有表达式都使用多行模式 |
rightContext | input字符串中lastMatch之后的文本 |
除了以上几个属性外,还有多达9个可以用于存储捕获组的构造函数属性。通过RegExp.$1,RegExp.\$2..访问
接下来我来说一下在字符串对象中的模式匹配问题
match()
在字符串中调用它,和调用上面说到的exec()是一样的。
match()接受一个参数,要么是一个正则表达式,要么是一个RegExp对象。
var text = "cat, bat, sat, fat";
var pattern = /.at/;
var matches = text.match(pattern);//与pattern.exec(text)一样
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern.lastIndex); //0
search()
该方法唯一的参数与match()方法的参数相同。
返回字符串中第一个匹配项的索引,没有则返回-1。
该方法始终都从字符串的开头开始往后找。
replace()
该方法用于替换字符串。不仅可以字符串替换字符串,也可以利用模式来替换所有匹配模式的字符串。
接受2个参数,第一个参数既可以是RegExp对象也可以是一个字符串,且这个字符串不会被解读为正则表达式的字面量。参数二可以是一个字符串或一个函数。
来看一个例子
var text = "cat, bat, sat, fat";
var res = text.replace("at","ond");
alert(res); //"cond, bat, sat, fat"
res = text.replace(/at/g,"ond");
alert(res); //"cond, bond, sond, fond"
当第二个参数是一个函数时。在只要一个匹配项的情况下,会向该函数传递3个参数:模式的匹配项,模式匹配项在字符串中的位置,原始字符串。若有多个捕获组,则在第一个参数和第二个参数中加上依次每个捕获组的匹配项作为参数。这个函数返回一个字符串,表示替换之后的匹配项。
说的有点绕,看一个例子就都明白了。
function htmlEscape(text){
return text.replace(/[<>"&]/g,fucntion(match,pos,originalText){
switch(match){
case "<":return "<";
case ">":return ">";
case "\"":return """;
case "&":return "&";
}
});
alert(htmlEscape("<p class=\"greet\">hello world!</p>"));
//<p class="greet">hello world!</p>
split()
基于指定的分隔符将字符串分割为多个字符串,并将结果放在一个数组中。可以传入2个参数,参数一是必须的,可以是字符串或者RegExp对象,参数二可选,用于指定数组的大小。
var colorText = "red,blue,green,yellow";
var colors = colorText.split(/[^\,]+/); //["",",",",",",",""]
关于模式匹配就说这么多了。
最后附上常见的正则表达式的一个链接
最全的常用正则表达式大全