2012-04-15 61 views
4

我想不通如何做一個用Javascript取代所有Javascript:全部替換字符串問題

我在一個特殊的情況,因爲我有一個更換地圖這樣的:

:) -> <img src="smile.png" title=":) "> 
    :( -> <img src="sad.png" title=":("> 
    >:( -> <img src="angry.png" title=">:("> 

我目前循環這張地圖上,併爲每個條目,我使用string.replace(from, to)。問題是我無法替換,例如>:(,因爲:(已被第二個條目取代。如果我反轉地圖,那麼title屬性中的:(將被替換,從而導致真正的混亂。

希望你瞭解我的情況。我需要像PHP str_replace這樣的數組參數,它可以在一次命中中進行多次替換。

如果可以幫助,我使用Mootools。

+0

你能給我們看一把小提琴嗎? – gdoron 2012-04-15 20:19:47

+0

在替換中使用全局集合的正則表達式! 'mystring.replace(/ something/g,'');' – adeneo 2012-04-15 20:19:52

+0

不要這樣做。確保您的用戶可以控制他們的輸入如何處理,例如通過使用Markdown。你冒着改變他們的輸入的風險,特別是如果他們被允許使用HTML。如果你真的想這樣做,那麼就可以正確解析他們的輸入,並且只對「常規」文本進行替換。 – Cameron 2012-04-15 20:21:40

回答

4

我會使用PHP的preg_replace_callback的模擬與正則表達式逃逸。

var putSmiles = (function(){ 
    // init part 
    var smilesMap = { 
    ':)': "smile", 
    ':(': "sad", 
    '>:(': "angry" 
    } 
    if (!('escape' in RegExp)) { 
    RegExp.escape = function(str) { 
     return str.replace(/./g, function(m){ 
     // IE (at least 8) doesn't support .substr(-4), hence MOAR regexes! 
     return "\\u" + ("0000" + m.charCodeAt(0).toString(16)).match(/.{4}$/)[0]; 
     }); 
    } 
    } 
    var a = []; 
    for (var s in smilesMap) a.push(RegExp.escape(s)); 
    // sort in such way, if b is substring of a, b should follow a. 
    a.sort(function(a,b){ return -a.indexOf(b) }); 
    var re = new RegExp(a.join('|'), 'g'); 
    // actual function 
    return (function(text) { 
    return text.replace(re, function(m){ 
     return '<img src="' + smilesMap[ m ] + '.png" title="' + m + '">'; 
    }); 
    }) 
})(); 
+0

爲什麼要用'arguments [0]'而不是命名參數? – Phrogz 2012-04-15 20:26:14

+0

+1,但'a.join()'應該是'' (?:'+ a.join(')|(?:')+')'',no? – Cameron 2012-04-15 20:26:44

+0

@phrogz沒有理由,也可以使用命名參數 – kirilloid 2012-04-15 20:26:54

1
var map = { 
    ":)" : '<img src="smile.png" title=":)">', 
    ":(" : '<img src="sad.png" title=":(">', 
    ">:(" : '<img src="angry.png" title=">:(">', 
}; 
str.replace(/>:\(|:\(|:\)/g, function(found){ 
    return map[found]; 
}); 

通過使用一次匹配所有三個正則表達式,您可以保證不會錯誤地選擇;使用replace的函數形式允許您確定替換字符串是動態的。

編輯:動態地逃避任何「特殊」字符的文本字符串的正則表達式中使用:

RegExp.escape = function(text) { 
    return text.replace(/[.?*^$()|{}\-\[\]\\]/g, "\\$&"); 
} 
+1

但是我如何使用我的替換映射這種方式呢?如果我爲每一個微笑運行這個正則表達式,不要再面對同樣的問題了嗎? – 2012-04-15 20:22:35

+0

@ lorenzo-s哦,對不起;我會編輯來解決這個問題。 – Phrogz 2012-04-15 20:23:09

+0

好的,但是whis不會解決我在問題中顯示的問題。如果我全部替換':(',那麼我無法正確替換'>:''。 – 2012-04-15 20:25:49