今天看到有人提問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)