tags:

views:

204

answers:

4

Hello, I have an array with:

emoticons = {
   ':-)' : 'smile1.gif',
   ':)'  : 'smile2.gif',
   ':D'  : 'smile3.gif'     
}

then i have a variabile with the text.

var text = 'this is a simple test :)';

and a variable with the url of the website

var url = "http://www.domain.com/";

How to write a function that replace the symbols with their images?

The <img> tag result should be:

<img src="http://www.domain.com/simple2.gif" />

(I have to concatenate the url varible to the name of the image).

THank you very much!

+1  A: 
for ( smile in emoticons )
{
   text = text.replace(smile, '<img src="' + url + emoticons[smile] + '" />');
}
Yossarian
It won't work correctly since replace replaces only the first ocurrence of the matched string.
Matias
Only works to replace the first occurance of each smiley. In a string like "This is replaced :) but not this :)" the second one is left unchanged.
Guffa
Also make sure to use `var` in the `for...in` statement, otherwise if the code is inside a function that doesn't declare the `smile` variable in that scope, it will become global, and using an `if (emoticons.hasOwnProperty(smile))` inside the loop is a good idea.
CMS
ok, so how to use .replace() to replace more then one occurence ?
Damiano
to replace more than one occurrence change `smile` to `new RegExp(smile, 'g')`
pepkin88
+9  A: 

Another approach:

function replaceEmoticons(text) {
  var emoticons = {
    ':-)' : 'smile1.gif',
    ':)'  : 'smile2.gif',
    ':D'  : 'smile3.gif'
  }, url = "http://www.domain.com/";
  // a simple regex to match the characters used in the emoticons
  return text.replace(/[:\-)D]+/g, function (match) {
    return typeof emoticons[match] != 'undefined' ?
           '<img src="'+url+emoticons[match]+'"/>' :
           match;
  });
}

replaceEmoticons('this is a simple test :)');
// "this is a simple test <img src="http://www.domain.com/smile2.gif"/&gt;"

Edit: @pepkin88 made a really good suggestion, build the regular expression based on the property names of the emoticons object.

It can be easily done, but we have to escape meta-characters if we want this to work properly.

The escaped patterns are stored on an array, that is later used to build the regular expression using the RegExp constructor, by basically joining all the patterns separated with the | metacharacter.

function replaceEmoticons(text) {
  var emoticons = {
    ':-)' : 'smile1.gif',
    ':)'  : 'smile2.gif',
    ':D'  : 'smile3.gif',
    ':-|'  : 'smile4.gif'
  }, url = "http://www.domain.com/", patterns = [],
     metachars = /[[\]{}()*+?.\\|^$\-,&#\s]/g;

  // build a regex pattern for each defined property
  for (var i in emoticons) {
    if (emoticons.hasOwnProperty(i)){ // escape metacharacters
      patterns.push('('+i.replace(metachars, "\\$&")+')');
    }
  }

  // build the regular expression and replace
  return text.replace(new RegExp(patterns.join('|'),'g'), function (match) {
    return typeof emoticons[match] != 'undefined' ?
           '<img src="'+url+emoticons[match]+'"/>' :
           match;
  });
}

replaceEmoticons('this is a simple test :-) :-| :D :)');
CMS
It would be even better if regexp was generated depending on keys values in `emoticons`.
pepkin88
@pepkin88: Great suggestion :), I've added a function that makes this possible.
CMS
This could be further enhanced by closing over the `replace()` (similar to [this answer](http://stackoverflow.com/questions/286921/javascript-efficiently-replace-all-accented-characters-in-a-string/614397#614397)…) - this would accelerate repeated calls to the function.
Tomalak
+4  A: 
var emoticons = {
   ':-)' : 'smile1.gif',
   ':)'  : 'smile2.gif',
   ':D'  : 'smile3.gif'     
}
var text = 'this is a simple test :)';
var url = "http://www.domain.com/";
for (var smile in emoticons) if (emoticons.hasOwnProperty(smile)) {
    text = text.split(smile).join('<img src="' + url + emoticons[smile] + '" />');
}
Lauri
A: 

Using a regex with an array of find replace elements works well.

var emotes = [
    [':\\\)', 'happy.png'],
    [':\\\(', 'sad.png']
];

function applyEmotesFormat(body){
    for(var i = 0; i < emotes.length; i++){
        body = body.replace(new RegExp(emotes[i][0], 'gi'), '<img src="emotes/' + emotes[i][1] + '">');
    }
    return body;
}
Ben Dauphinee