正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,模式描述在搜索文本时要匹配的一个或多个字符串。
JavaScript通过RegExp来支持正则表达式。正则表达式创建方式 var reg=/pattern/flags。其中pattern可以是任何简单或者复杂的正则表达式,可以包含字符串、分组、限定符、向前查找以及方向引用。每个正则表达式可以带有一个或者多个标记,用以表达正则表达式的行为。正则表达式匹配模式包含3个标记:
g:表示全局模式,模式应用于所有字符串,而非发现第一个匹配项立即停止。
i:表示不区分大小写,在确定匹配项时忽略模式与字符串的大小写。
m:多行模式,在到达一行末尾时,还会继续查找下一行中是否存在于模式匹配的项。
因此,一个正在表达式就是一个模式与3个标记的组合体,不同的组合产生不同的效果。模式中使用的元字符必须转义,元字符包括( [ { ^ $ | ) ? * + . ] }。
//匹配字符串中所有at的实例 var pattern1 =/at/g; //匹配字符串中一个‘bat’或者‘cat’,不区分大小写 var pattern2=/[bc]at/; //匹配字符串中所有以at结尾的三个字符串,不区分大小写 var pattern3=/.at/gi; //匹配字符串中一个[bc]at,不区分大小写 var pattern4=/[bc]at/; //匹配字符串中所有以.at,不区分大小写 var pattern5=/.at/gi;
上述代码中 pattern1匹配字符串中所有at的实例,pattern2匹配字符串中第一个bat或者cat,不区分大小写。pattern3匹配字符串中以at结尾的三个字符串,不区分大小写。pattern4匹配字符串中第一个[bc]at的字符,不区分大小。这里对[]进行了转义。pattern5同样进行了转义,所以匹配字符串中所有.at字符。
var pattern6 = new RegExp("\.at","gi");
通过RegExp函数定义的正则表达式与字面量定义的有点不同。上面的pattern6与pattern5是一样的效果,但是RegExp的两个参数都是字符串,所以需要对第一个参数的字符进行双重转义。
for(var i=0;i<10;i++){ var pattern=/at/g; var index=pattern.test("cathello"); }
RegExp的每个实例都有以下属性:
global:布尔值,表示是否设置了g标志;
ignoreCase:布尔值,表示是否设置了i标志;
lastIndex:表示开始搜索下一个匹配项的字符位置,从0开始;
mutilline:表示是否设置了m标记
source:正则表达式的字符串表示;
RegExp的实例方法exec,可以捕获组。exec方法接受一个参数,就是要进行应用模式的字符串。返回包含第一个匹配项信息的数组,在没有匹配项的情况下返回null。返回的数字是Array实例,但是包含index和input两个属性。index表示匹配项的位置,input表示应用正则表达式的字符串。
如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null。此数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个子表达式相匹配的文本(如果有的话),以此类推。除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。我们可以看得出,在调用非全局的 RegExp 对象的 exec() 方法时,返回的数组与调用方法 String.match() 返回的数组是相同的。
但是,当 RegExpObject 是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。
如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串,就必须手动地把 lastIndex 属性重置为 0。
function RegExpTest() { var src = "The rain in Spain falls mainly in the plain."; var re = /(w+)/g; // 创建正则表达式模式。 var arr; while((arr = re.exec(src)) != null) { //document.write(arr.index + "-" + RegExp.lastIndex + " " + arr[0]); //此处RegExp.lastIndex和arr.lastIndex均有同样的属性,可以互换。在此注意IE6和7的lastIndex重设置0的bug console.log(arr.index+"-"+re.lastIndex+"-"+arr[0]); } }; RegExpTest();
如果上面的正则表达式不是全局表达式,则上述循环为死循环,因为re的lastindex在执行之后,属性被重置为0,所以循环一直在0,3处循环。
正则表达式的第二个方法是test(),它接受一个字符串参数,在模式与该参数匹配的情况下,返回true;否则返回false。在只想知道目标字符串与模式是否匹配时,可以使用test方法。test方法经常被用在if中。
var pattern1 =/at/g; if(pattern1.test("cat")){ console.log("the pattern is matched"); }
上面的代码test方法返回true。
JavaScript的模式匹配有一定局限性,如向后查找,并集和交集等。