2013-08-16 16 views
0

我有以下使用大量正則表達式的javascript函數。有什麼辦法可以簡化這個嗎?Javascript:簡化許多正則表達式.replace()爲更少的正則表達式調用

function encode(str){ 
    if(typeof str==='number'){ 
     return str; 
    } 
    if(typeof str!=='string'){ 
     return ''; 
    } 
    var enc=str; 
    enc=enc.replace(/_/g,'_u'); //underscore 
    enc=enc.replace(/(\r\n|\r|\n)/g,'_r'); //return 
    enc=enc.replace(/&/g,'_a'); //ampersand 
    enc=enc.replace(/\\/g,'_b'); //backslash 
    enc=enc.replace(/:/g,'_c'); //colon 
    enc=enc.replace(/"/g,'_d'); //double quote 
    enc=enc.replace(/=/g,'_e'); //equals 
    enc=enc.replace(/€/g,'_4'); //euro 
    enc=enc.replace(/\>/g,'_g'); //greater than 
    enc=enc.replace(/#/g,'_h'); //hash 
    enc=enc.replace(/'/g,'_i'); //inverted comma 
    enc=enc.replace(/\</g,'_l'); //less than 
    enc=enc.replace(/¬/g,'_n'); //not 
    enc=enc.replace(/\|/g,'_1'); //pipe 
    enc=enc.replace(/¦/g,'_2'); //broken pipe 
    enc=enc.replace(/\+/g,'_p'); //plus 
    enc=enc.replace(/£/g,'_3'); //pound 
    enc=enc.replace(/\?/g,'_q'); //question mark 
    enc=enc.replace(/\//g,'_s'); //slash 
    enc=enc.replace(/\~/g,'_t'); //tlide 
    enc=enc.replace(/\`/g,'_z'); //back quote 
    enc=enc.replace(/\s/g,'_0'); //space 
    enc=enc.replace(/[\u0000-\u001f]/g,''); 
    return enc; 
}; 
+0

最終你的狀況是什麼。你想用一些你的東西替換所有的特殊字符。不是嗎? – user2587222

+0

你爲什麼要改變它? –

+0

你應該描述一下你想用正則表達式來做一些例子,然後有人會幫助你。 –

回答

1

你可以做這樣的事情:

var map = { 
    "_": "_u", 
    "(\r\n|\r|\n)": "_r", 
    "&": "_a", 
    /* .. etc .. */ 
}; 
var i; 
var enc = "_abc&"; 
for (i in map) { 
    enc = enc.replace(new RegExp(i, "g"), map[i]); 
} 
console.log(enc); // _uabc_a 

我以前new RegExp,因爲你不能構成一個正則表達式。請記住,您不需要分隔符(/),而修飾符(g)位於其他位置。

+0

不是這個正則表達式調用的數量,只是在for循環? – Jimmery

+0

它是。我看不到其他的方式來優化,所以我想你是這個意思。 – Halcyon

+0

好的謝謝。我期待着看看我是否可以優化這一點,但如果我不能那麼回答我的問題。 – Jimmery

3

而不是創建地圖「模式」爲「更新換代」,你可以改爲從創建地圖「字符串替換」到「替代」,然後使用一個替代函數的回調:

var map = { 
    "_": "_u", 
    "\r\n": "_r", 
    "\r": "_r", 
    "\n": "_r", 
    "&": "_a", 
    /* .. etc .. */ 
}; 

enc = enc.replace(
     /\r\n|[_\r\n&\\:"=€>#'<¬|¦+£?\/~`\s\u0000-\u001f]/g, 
     function(m) { 
      return map[m[0]]; 
     } 
); 

只要添加不會導致固定字符串的替換模式(因爲它們使用的量詞類似+*),此方法就會失敗。

但是,它在大多數瀏覽器中實際上顯着更快。請參閱this JSPerf

除此之外,沒有辦法做條件替換(這是你需要進一步優化)。

+0

+1我很好奇,如果這個解決方案如果直接放在回調函數中(作爲一個匿名對象文字)就會放慢速度?例如's.replace(/ [<>&]/g,function(m){return {「<」:「」<「,」>「:」>「,」&「:」&「} [m];} )' – ridgerunner

+0

@ridgerunner在生產代碼中,我實際上將'map'拉得更遠並使其成爲「全局」,因此每次有人調用'encode'時都不必創建它。 –

相關問題