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;
代碼復雜度稍有提升,但是原理與上面一樣,各位自己讀下吧,今天的學習到此
