How to replace strings with javascript?
I have this function:
function emoticons(text){
var url = "http://www.domain.it/images/smilies/";
var emt = {
":D" : 'icon_e_biggrin.gif',
":-D" : 'icon_e_biggrin.gif',
":)" : 'icon_e_smile.gif',
":-)" : 'icon_e_smile.gif',
";)" : 'icon_e_wink.gif',
"开发者_StackOverflow社区';-)" : 'icon_e_wink.gif',
":(" : 'icon_e_sad.gif',
":-(" : 'icon_e_sad.gif',
":o" : 'icon_e_surprised.gif',
":?" : 'icon_e_confused.gif',
"8-)" : 'icon_cool.gif',
":x" : 'icon_mad.gif',
":P" : 'icon_razz.gif'
};
for (smile in emt){
text = text.replace(smile, '<img src="' + url + emt[smile] + '" class="emoticons" />');
}
return (text);
}
As you know .replace() convert the first occurence, how to replace more then one emoticon inside the text? How to change this function?
Thank you very much!
You could translate each emoticon string to a global regular expression, which will replace all occurrences when used with the String#replace method:
function emoticons(text){
var url = "http://www.domain.it/images/smilies/";
var emt = {
/\:D/g: 'icon_e_biggrin.gif',
/\:\-D/g: 'icon_e_biggrin.gif',
//...
You'll have to be careful about escaping special characters in the emoticon text though.
maerics' answer is a fairly small change to your existing function that should do the trick. If the text you're doing these replacements in is large, though, you might consider flipping things on their head and using a regex alternation and a replacement function.
Regex alternations look like this: /A|B|C/
, which tells the regex engine to look A or B or C. The function you give to String#replace
receives the matching text as an argument, so it can then look up the relevant replacement in a map:
function emoticons(text){
// The base URL of all our smilies
var url = "http://www.domain.it/images/smilies/";
// A regex alternation that looks for all of them (be careful to use escapes
// where necessary)
var searchFor = /:D|:-D|:\)|:-\)|;\)|';-\)|:\(|:-\(|:o|:\?|8-\)|:x|:P/gi;
// A map mapping each smiley to its image
var map = {
":D" : 'icon_e_biggrin.gif', // Capped version of the next
":d" : 'icon_e_biggrin.gif', // Lower case version of the previous
":-D" : 'icon_e_biggrin.gif', // Capped version of the next
":-d" : 'icon_e_biggrin.gif', // Lower case version of the previous
":)" : 'icon_e_smile.gif',
":-)" : 'icon_e_smile.gif',
";)" : 'icon_e_wink.gif',
"';-)" : 'icon_e_wink.gif',
":(" : 'icon_e_sad.gif',
":-(" : 'icon_e_sad.gif',
":O" : 'icon_e_surprised.gif', // Capped version of the next
":o" : 'icon_e_surprised.gif', // Lower case version of the previous
":?" : 'icon_e_confused.gif',
"8-)" : 'icon_cool.gif',
":X" : 'icon_mad.gif', // Capped version of the next
":x" : 'icon_mad.gif', // Lower case version of the previous
":P" : 'icon_razz.gif', // Capped version of the next
":p" : 'icon_razz.gif' // Lower case version of the previous
};
// Do the replacements
text = text.replace(searchFor, function(match) {
var rep;
// Look up this match to see if we have an image for it
rep = map[match];
// If we do, return an `img` tag using that smiley icon; if not, there's
// a mis-match between our `searchFor` regex and our map of
// smilies, but handle it gracefully by returning the match unchanged.
return rep ? '<img src="' + url + rep + '" class="emoticons" />' : match;
});
return (text);
}
Doing this lets you only loop through the string once and build a single replacement string, rather than looping through it for each smiley and building multiple interim strings.
For smallish bits of text it won't matter and the complexity (maintaining each smiley in two different places) may not be worth it, but for large texts it may be.
Another solution is to create a RegExp with the "g" modifier for each string. And since this function may be run more than once par pageload, you should create emt
and the regexps only once:
var emoticons = (function () {
var url = "http://www.domain.it/images/smilies/";
var emt = {
":D" : 'icon_e_biggrin.gif',
":-D" : 'icon_e_biggrin.gif',
":)" : 'icon_e_smile.gif',
":-)" : 'icon_e_smile.gif',
";)" : 'icon_e_wink.gif',
"';-)" : 'icon_e_wink.gif',
":(" : 'icon_e_sad.gif',
":-(" : 'icon_e_sad.gif',
":o" : 'icon_e_surprised.gif',
":?" : 'icon_e_confused.gif',
"8-)" : 'icon_cool.gif',
":x" : 'icon_mad.gif',
":P" : 'icon_razz.gif'
};
var patterns = [];
for (smile in emt) {
patterns.push([
// escaping string special characters by hand
// case-insensitive to match :p :d etc.
new RegExp(smile.replace(/([\(\)\[\]\{\}\.\?\^\$\|\-])/g, "\\$1"), "gi"),
'<img src="' + url + emt[smile] + '" class="emoticons" />'
]);
}
// this is the function that will be referenced by the variable emoticons
return function (text) {
for(var i=0; i<patterns.length; i++) {
text = text.replace(patterns[i][0], patterns[i][1]);
}
return text;
}
})();
Here is a demo: http://jsfiddle.net/gjfzf/2/
精彩评论