ECMAScript通过RegExp类型来支持正则表达式。
1、 创建一个正则表达式:
var expression=/pattern/flags;
其中的模式(pattern)部分可以是任何简单或复杂的正则表达式,可以包含字符类、限定符、分组、向前查找以及反向引用。每个正则表达式都可带有一个或多个标识(flags).用以标明正则表达式的行为。正则表达式的匹配模式支持下列3个标识:
①g: 表示全局模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即停止;
②i: 表示不区分大小写模式,即在确定匹配项时忽略模式与字符串的大小写;
③m:表示多行模式,即在到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项。
与其他语言中的正则表达式类似,模式中使用的所有元字符都必须转义。正则表达式中的元字符包括:
()[]{}\^$|?*+.
这些元字符在正则表达式中都有一种或多种特殊用途,因此如果想要匹配字符串中包含的这些字符,就必须对它们进行转义。
例如: 匹配第一个" [bc]at ",不区分大小写
var pattern=/\[bc\]at/i;
匹配所有以" at "结尾的3个字符的组合,不区分大小写
var pattern=/.at/gi;
匹配所有的" .at ",不区分大小写
var pattern=/\.at/gi;
以上例子都是以字面量形式来定义的正则表达式。
另一种创建正则表达式的方式是使用RegExp构造函数,他接收两个参数:一个是要匹配的字符串模式,另一个是可选的标志字符串。
var pattern=new RegExp("[bc]at","i");
等价于
var pattern=/[bc]at/i; //匹配第一个bat或cat,不区分大小写
注意: 传递给RegExp构造函数的两个参数都是字符串(不能把正则表达式字面量传递给RegExp构造函数),由于RegExp构造函数的模式参数都是字符串,所以在某些情况下要对字符进行双重转义。所有元字符都必须双重转义,那些已经转义过的字符也是如此。 例如\n(字符\在字符串中通常被转义为\\,而在正则表达式字符串中就会变成\\\\)。
字面量模式 | 等价的字符串 |
/\[bc\]at/ | '\\[bc\\]at' |
/\.at/ | '\\.at' |
/name\ /age/ | 'name\\/age' |
/\d.\d{1,2}/ | '\\d.\\d{1,2}' |
/\w\\hello\\123/ | '\\w\\\\hello\\\\123' |
① global: 布尔值,表示是否设置了g标志。
②ignoreCase: 布尔值,表示是否设置了i标志
③lastIndex:整数,表示开始搜索下一个匹配项的字符位置,从0算起。
④multiline: 布尔值,表示是否设置了m标志
⑤source: 正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回。
3、RegExp实例方法
3.1、 RegExp对象的主要方法是exec(),该方法是专门为捕获组而设计的。exec()接受一个参数,即要应用模式的字符串,然后返回包含第一个匹配项信息的数组;或者在没有匹配项的情况下返回null。返回的数组虽然是Array的实例,但包含两个额外的属性: index和input。其中,index表示匹配项在字符串中的位置,而input表示应用正则表达式的字符串。在数组中,第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串(如果模式中没有捕获组,则该数组只包含一项)。
请看下面的例子:
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"
这个例子中的模式包含两个捕获组。最内部的捕获组匹配"and baby",而包含它的捕获组匹配"and dad"或者"and dad and baby"。当把字符串传入exec()方法中之后,发现了一个匹配项。因为整个字符串本身与模式匹配,所以返回额数组matches的index属性值为0.数组中的第一项是匹配的整个的字符串,第二项包含与第一个捕获组匹配的内容,第三项包含与第二个捕获组匹配的内容。
对于exec()方法而言,即使在模式中设置了全局标志(g),他每次也只会返回一个匹配项,在不设置全局标志的情况下,在同一个字符串上多次调用exec()将始终返回第一个匹配项的信息。而在设置了全局标志的情况下,每次调用exec()则都会在字符串中继续查找新匹配项。
var text="cat,bat,sat,fat";
var pattern=/.at/;
var matches=pattern.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern.lastIndex); //0
matches=pattern.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern.lastIndex); //0
var pattern2=/.at/g;var matches=pattern2.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern2.lastIndex); //0
matches=pattern2.exec(text);
alert(matches.index); //5
alert(matches[0]); //bat
alert(pattern2.lastIndex); //8
注意: IE的javascript实现lastIndex属性上存在偏差,即使在非全局模式下,lastIndex属性每次也会变化。
3.2、正则表达式的第二个方法是test(),他接收一个字符串参数。在模式与该参数匹配的情况下返回true;否则,返回false。在只想知道目标字符串与某个模式是否匹配,但不需要知道其文本内容的情况下,使用这个方法非常方便。
var text="000-00-0000";
var pattern=/\d{3}-\d{2}-\d{4}/;
if(pattern.test(text)){
alert("模式匹配");
}
RegExp实例继承的toLocaleString()和toString()方法都会返回正则表达式的字面量,与创建正则表达式的方式无关。例如:
var pattern=new RegExp("\\[bc\\]at","gi");
alert(pattern.toString()); // 结果:/\[bc\]at/gi
alert(pattern.toLocaleString()); //结果:/\[bc\]at/gi
即使上例中的模式是通过调用RegExp构造函数创建的,但toLocalestring()和toString() 方法仍然会像它是以字面量形式创建的一样显示其字符串表示。