javascript字串與陣列有很多精巧的方法,比如splice、indexOf,而replace在字串處理中偶爾會產生讓人愉悅的效果
比如underscore中的模板引擎替換部分,又如信用卡分割的應用
簡單來說,replace用於將字串中一些字元替換為另一些字元,最簡單的情況如下
var num = '1234567890123456'; var numStr = ''; numStr = num.replace('1', 'a'); console.log(numStr);//a234567890123456
這個結果,事實上不太理想,因為他只替換了一個,後面的1沒有理我,於是這個時候正則便出現了
var num = '1234567890123456'; var numStr = ''; numStr = num.replace(/1/g, 'a'); console.log(numStr); //a234567890a23456
一個經典例子是,javascript實現的trim方法
String.prototype.trim = function () { return this.toString().replace(/(^\s*)|(\s*$)/g, ''); }; var str = ' sssssds '; alert('|' + str.trim() + '|'); //|sssssds|
正則出現的時候便會有一些比較特殊的標識“$”
字元 | 替換文字 |
---|---|
$1、$2、...、$99 | 與 regexp 中的第 1 到第 99 個子表示式相匹配的文字。 |
$& | 與 regexp 相匹配的子串。 |
$` | 位於匹配子串左側的文字。 |
$' | 位於匹配子串右側的文字。 |
$$ | 直接量符號。 |
var str = ' 123 '; console.log(str.replace(/(^\s*)|(\s*$)/g, '-$&-')); //- -123- ---
一切都很美好的時候,不滿足的情況發生了,我們感覺這個結果與預期不符,具體原因我們後面再說,這裡先看看函式回撥情況
var str = ' 123 '; var arr = []; /* 引數一為匹配到的字串 引數二為子表示式中的資料對應( $i (i:1-99)),帶|號便會產生(注意這裡可能產生多個引數匹配) 引數三為匹配字串的匹配下標 最後一個參數列示字串本身 */ console.log(str.replace(/(^\s*)|(\s*$)/g, function (match, $1, $2, offset) { console.log(arguments); arr.push('-' + (match || '') + '-'); return '-' + (match || '') + '-'; })); console.log(arr); //- -123- ---
以上其實想簡單說明下函式與$的關係,導致輸出的原因是因為正則沒有寫對:
var str = ' 123 '; console.log(str.replace(/^(\s+)|(\s+)$/g, '-$&-'));
PS:上面那個正則還是抄的,所以以後碰到類似問題還是得自己驗證才行啊
另外,我有一個信用卡賬號要做格式轉換:123456789012 => 1234 5678 9012
這個程式碼要用replace的話,不用函式便行不通的
一旦匹配成功,會替換為後面函式的的返回值,這個函式匹配成功幾次便會呼叫幾次,有些時候我們可以把它當做一個迴圈使用
var num = '123456789012'; var reg = /\d{4}/g; var index = 0; var arr = []; num.replace(reg, function (match, offset) { arr.push(match); }); console.log(arr.join(' ')); //1234 5678 9012
最後我們來看看我們的underscore模板引擎語法,現在我們有一個模板字串,我們要將它轉換為一個函式,於是我們會這麼做
1 var template = [ 2 '<ul class="ul-list" style="position: absolute; width: 100%; top: 0; left: 0;">', 3 '<%for(var i = 0, len = data.length; i < len; i++) { %>', 4 '<li data-key="<%=data[i].id %>" data-index="<%=i%>" <%if(data[i].disabled){ %> class="disabled"', 5 '<%} %>>', 6 '<%=data[i].name %></li>', 7 '<%} %>', 8 '</ul>', 9 '<div class="cui-mask-gray">', 10 '</div>', 11 '<div class="cui-lines">', 12 ' </div>' 13 ].join(''); 14 15 var escapes = { 16 "'": "'", 17 '\\': '\\', 18 '\r': 'r', 19 '\n': 'n', 20 '\t': 't', 21 '\u2028': 'u2028', 22 '\u2029': 'u2029' 23 }; 24 var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; 25 26 var index = 0; 27 var source = "__p+='"; 28 var matcher = /(<%-[\s\S]+?)%>|<%=([\s\S]+?)%>|<%([\s\S]+?)%>|$/g; 29 30 template.replace(matcher, function (match, escape, interpolate, evaluate, offset) { 31 source += template.slice(index, offset) 32 .replace(escaper, function (match) { return '\\' + escapes[match]; }); 33 34 if (escape) { 35 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; 36 } 37 if (interpolate) { 38 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; 39 } 40 if (evaluate) { 41 source += "';\n" + evaluate + "\n__p+='"; 42 } 43 index = offset + match.length; 44 return match; 45 }); 46 source += "';\n"; 47 48 source = 'with(obj||{}){\n' + source + '}\n'; 49 50 source = "var __t,__p='',__j=Array.prototype.join," + 51 "print=function(){__p+=__j.call(arguments,'');};\n" + 52 source + "return __p;\n"; 53 54 console.log(source);
上面的程式碼列印出的東西:
var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');}; with(obj||{}){ __p+='<ul class="ul-list" style="position: absolute; width: 100%; top: 0; left: 0;">'; for(var i = 0, len = data.length; i < len; i++) { __p+='<li data-key="'+ ((__t=(data[i].id ))==null?'':__t)+ '" data-index="'+ ((__t=(i))==null?'':__t)+ '" '; if(data[i].disabled){ __p+=' class="disabled"'; } __p+='>'+ ((__t=(data[i].name ))==null?'':__t)+ '</li>'; } __p+='</ul><div class="cui-mask-gray"></div><div class="cui-lines"> </div>'; } return __p;
程式碼複雜度稍有提升,但是原理與上面一樣,各位自己讀下吧,今天的學習到此