正则表达式中各种方法的用法和比较(更多信息参考)
RegExp的exec方法总结:
(1)第0个元素是与表达式匹配的文本
(2)第1个元素是与子表达式匹配的文本,捕获组
(3)很显然返回值是数组
(4)返回数组有length,index(匹配文本第一个字符位置),input(整个字符串)属性
var rts = /([?&])_=[^&]*/; var cacheURL="http://localhost:8080/qinl/xx.action?_=me"; var result=rts.exec(cacheURL); console.log(result);通过 该图,你会发现返回的元素个数是2,同时有index属性表示开始匹配的下标,input表示传入正则表达式的字符串!
(5)非全局的正则执行exec和match方法完全一致!
var rts = /([?&])_=[^&]*/; var cacheURL="http://localhost:8080/qinl/xx.action?_=me"; var result=rts.exec(cacheURL); console.log(result);//一样 var result1=cacheURL.match(rts); console.log(result1);//一样通过 该图,你会发现非全局的正则表达式exec和match的结果完成一样!
(6)当全局正则执行exec时候会有lastIndex属性表示下一次搜索下标,当exec再也找不到匹配的文本时候返回null,并且把lastIndex重置为0
String对象的test方法:
(1)使用正则表达式字面量和RegExp构造函数创建的正则表达式不一样,在ECMAScript3中,字面量始终共享同一样RegExp实例,而构造函数创建的每一个新的RegExp都是一个新实例。ECMA5中相同
(2)source属性中保存的是规范形式的字符串,也就是字面量形式的字符串。同时还包含global,multiline,lastIndex,ignoreCase属性!
(3)在IE中即使在非全局模式下,lastIndex也会一直变化!
(4)RegExp的toLocalString和toString都会返回正则表达式的字面量,与创建方式无关!
(5)正则表达式的valueOf返回正则表达式本身!
(6)正则表达式的长属性名和短属性名可以从exec和test方法中取出更具体的信息,但是Opera不支持短属性名!
(7)可以通过RegExp.$1访问第一个捕获组,依次类推,可以用于test,exec方法等
(8)input($_)表示最近一次要匹配的字符串,lastMatch($&)最近一次的匹配项,leftContext($`)表示lastMatch之前的文本,rightContext($')lastMatch右边的文本,multiline是否支持多行匹配!lastParen($+)最近一次的捕获组。Opera只支持leftContex和rightContext
IE不支持multiline属性!
String对象的replace方法:
(1)第一个参数表示执行匹配的正则表达式,也可以传递字符串,第二个参数表示准备代替匹配的字符串,也就是用第二个参数替换第一个参数的内容!
(2)replace方法不会把字符串转为正则表达式,而是以字符串直接量的文本模式进行匹配,第二个参数可以是替换的文本,或者生产匹配文本的函数!
(3)如果正则表达式具有全局性质那么就会替换所有的匹配字符串,否则只是替换第一个匹配字符串
(4)replace方法传入的第一个形参是每次匹配的文本,接着$2….$n是捕获组的值,接着的形参是匹配文本的下标,接着的形参是要执行匹配的字符串,也就是调用replace方法的字符串,一直不变!
var s='script language="javascript" type=" text/javascript "'; var f=function($1) { return $1.substring(0,1).toUpperCase()+$1.substring(1); } //对每一个单词都作用单独处理\b表示单词边界,而且是全局的! //传入第二个函数的参数顺序是:每次匹配的文本(这里是单词),然后顺次是捕获组的值,然后是匹配字符在下标中的位置 //最后一个参数表示字符串本身! var a=s.replace(/(\b\w+\b)/g,f); //打印Script Language="Javascript" Type=" Text/Javascript " console.log(a);这个例子实现了所有单词的首字母大写,但是没有完全利用正则表达式给我们传入的所有的参数,所以我们可以做下面的修改:
var f=function($1,$2,$3) { return $2.toUpperCase()+$3; } //对每一个单词都作用单独处理\b表示单词边界,而且是全局的! //传入第二个函数的参数顺序是:每次匹配的文本(这里是单词),然后顺次是捕获组的值,然后是匹配字符在下标中的位置 //最后一个参数表示字符串本身! var a=s.replace(/\b(\w)(\w*)\b/g,f); console.log(a);这时候我很好奇,如果是match会是怎么的
var s='script language="javascript" type=" text/javascript "'; var result=s.match(/\b(\w)(\w*)\b/g); //打印["script", "language", "javascript", "type", "text", "javascript"] console.log(result)下面我们给出match和exec的区别:
表1:(match和exec方法的区别)
全局(g) | 非全局 | |
有捕获组 |
(1)exec返回的数组只包含第一个匹配字符串和捕获组的数据,如果多次调用,那么会通过lastIndex不断返回新的结果 (2)match返回所有的匹配的结果,不包含捕获组,捕获组通过$n访问 |
(1)match和exec方法一样只是返回第一个匹配字符串和捕获组 |
无捕获组 |
(1)exec只返回第一个匹配元素,match返回所有的匹配元素 (2)如果多次在该RegExp中调用exec方法,那么会返回新的结果! |
(1)match和exec方法一致,只是返回第一个匹配字符串组 |
note:非全局下match和exec一样。全局模式下,exec只是包含第一个匹配字符串和捕获组,match返回的是所有匹配的结果!
例1:(阅读点击打开链接)
通过循环结构反复调用exec是唯一获得全局模式的完整模式匹配信息的方法,无论正则表达式是否为全局模式,exec都会将完整的信息添加到返回数组中。字符串对象的match方法就不同,它在全局模式下返回的数组不包括那么多细节信息!
vars="java"; var r=/\w/g; while((a=r.exec(s))!=null) { //a.length是1,a[0]就是每次匹配的一个字符,index就是匹配文本第一个字符的位置,input包含的是整个字符串 //a.input每次打印的都是一样的,结果是"java" //a[0]第一次打印j,第二次为a,第三次是v,第四次是a //a.index第一次打印0,第二次是1,第三次是2,第四次是3 alert(a.length+"\n"+a[0]+"\n"+a.index+"\n"+r.lastIndex+"\n"+a.input); }
注意:如果把上面的正则表达式的g去掉,那么就不会有lastIndex,于是每次打印的结果都是一样的,为[1,"j",0,0,"java"]。通过该图你就会发现全局模式下的exec保存的所有的信息!
例2:(正则表达式的贪婪和懒惰用法)
var s="abcd-abcd-abcd"; var reg=/(abcd-?)*/; var result=s.match(reg); //打印[abcd-abcd-abcd,abcd]其中问号表示出现0次或者1次,尽量少次数! alert(result); //(1)首先匹配"<" //(2)直接匹配"html"字符串 //(3)直接绕过(\s)*?匹配字符">",最后首先得到的字符就是"<html>" //(4)然后依次扩展前面的*?表达式! //总结:*?是懒惰匹配,所以在第一次匹配的时候直接绕过他匹配下面的字符! var s1="<html>< html><html >< html ></html>< /html></ html>< / html ><///html>"; var reg1=/<([\/\s]*?)html(\s)*?>/g; alert(s1.match(reg1)); //打印[<p>title<p>,<h1>text<h1>] //在同一个正则表达式的后面可以用\n引用前面的第n个捕获组的结果,记住:这里是结果不是前面的正则表达式模式! //而是匹配的结果,如果要用前面的模式就要把前面的正则表达式重新书写一次。同时因为子表达式可以嵌套在其它子表达式中,因此他的位置编号是根据左边括号的顺序来编号的! var s2="<h1>titile<h1><p>text<p>"; var reg2=/(<\/?\w+>).*\1/g; alert(s2.match(reg2)); //实现数字和字母的顺序颠倒 var s3="aa11bb22c3d4e5f6"; var reg3=/(\w+?)(\d+)/g; alert(s3.replace(reg3,"$2$1"));