2012-04-15 126 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