今天看到有人提问js的replace方法怎么实现的,本身就试了试
js手册里的String对象的介绍replace大概是这样:正则表达式
string.replace(regexp, replacement)
第一个参数:(regexp)数组
声明了要替换的模式的RegExp对象。若是该参数是一个字符串,则将它做为要检索的直接量文本模式,而不是首先被转换成RegExp对象。
第二个参数(replacement)函数
一个字符串,声明的是替换文本或生成替换文本的函数。详见描述部分。
返回值测试
一个新字符串,是用replacemenc替换了与regexp的第一次匹配或全部匹配以后获得的。
我就试着实现了下一开始思路没考虑到正则,有不少问题,通过修改过的思路:this
使用了正则的exec(),用split将匹配到的字符串做为参数把原字符串分割成若干数组,而后将字符串和替换的内容链接join起来就实现了prototype
exec()将检索字符串string,从中获得与正则表达式regexp相匹配的文本。若是exec()找到了匹配的文本,它就会返回一个结果数组。不然,返回null。
匹配到的第一个数组[0]:匹配的文本,debug
第2个元素是与regexp的第二个子表达式相匹配的文本,以此类推。一般,数组的length属性声明的是数组中的元素个数。除了数组元素和length属性以外,exec()还返回两个属性。index属性声明的是匹配文本的第一个字符的位置。input属性指的就是string。在调用非全局RegExp对象的exec()方法时,返回的数组与调用方法String.match()返回的方法相同。
String.prototype.replaces=function(reg,str){ var arr = []; var newStr= this; var i= ''; //循环到 匹配不到替换的字符串为止 while(reg.exec(newStr)!='null') { /**使用try,catch是由于在循环到匹配到全部!=null下次循 环reg.exec(newStr)[0]会报错,循环完到报错时直接return结果**/ try{ arr = newStr.split(reg.exec(newStr)[0]); newStr = arr.join(str); //若是该正则式子不是全局正则(/g)不做循环直接修改一次返回 if(!reg.global){ return newStr; } }catch(e){ return newStr; } } } console.log("我是AbCd啊abcd啊abcd".replaces(/abcd/gi,'lipengpeng')) ---------------------------------------------------- 通过测试,上面代码存在的问题以下: 当正则表达式是全局时(/g)时,且只匹配到一个,会直接返回原字符串, 在循环reg.exec(newStr)时,每次结果都不同,这里暂时不清楚缘由 修改后的: String.prototype.replaces=function(reg,str){ var arr = []; var newStr= this; var i= ''; var d; //为了防止reg.exec()每次结果不同,直接赋给一个变量 //这里注意给d=reg.exec()加括号, “=”的优先级低 while((d = reg.exec(newStr))!=null) { try{ arr = newStr.split(d[0]); newStr = arr.join(str); if(reg.global){ return newStr; }else{ break; } }catch(e){ console.log(e) } } }
---------------------------------分割线-------------------------------------code
以上代码继续测试后,发现若是正则匹配到不区分大小写(/i)且不开启全局匹配,结果会全局替换。添加非全局代码,不用管大小写在全局或非全局(正则已经处理过),最终代码:regexp
String.prototype.replaces = function(reg, str) { var arr = []; var newStr = this; var i = ''; var d; while((d = reg.exec(newStr)) != null) { //debugger try { //console.log(d) if(reg.global) { arr = newStr.split(d[0]); newStr = arr.join(str); } else { var index = d['index']; var lastindex = (+index) + (+d[0].length); var preStr = newStr.slice(0, index); var nextStr = newStr.slice(lastindex); newStr = preStr + str + nextStr; break; } } catch(e) { console.log(e) } } return newStr } var s = "我是A,c,a,cc,c,c,cc,a".replaces(/a/ig, 'b') console.log(s)