1

I have a list of emojies like:

var emojies = ["smile", "smiley", "grin", "joy"];

And I want to detect and replace the :emoji_name: by <span class='emoji emoji_name'></span> with a function, for example, if text is: Hi guys! :smile:, replace the :smile: by <span class='emoji smile'></span> and i guess regex solve this, but, how to do?

Igor
  • 645
  • 4
  • 16
  • 37
  • 3
    Can you show us what you have tried? – talemyn Jun 12 '15 at 20:09
  • you can use regular expressions if you want to pull out all of your hair, if you no no hail then fingernails might suffice. If you are not opposed you could try using JQuery to search the DOM and replace based on contents. Alternatively there are a number of source code bases if you just search for `javascript emoji parser` – hoss Jun 12 '15 at 20:11
  • I was trying with answer in following link: http://stackoverflow.com/questions/3055515/replace-a-list-of-emoticons-with-their-images but have no success. I'm begginer, so, regex is very hard for me :/ – Igor Jun 12 '15 at 20:12
  • And, I don't know if `regex` is the best way for this but it is what I thought. – Igor Jun 12 '15 at 20:17

3 Answers3

3

join your array and create a single regex, then you can use replace with a callback function (or use the single line replace like in sln's answer) to create the spans

Note this assumes all emoji names are between :

var emojies = ["smile", "smiley", "grin", "joy"];
//Create a single regex
var regex = new RegExp(":("+ emojies.join("|") +"):","g");
/* Will result in /:(smile|smiley|grin|joy):/g
 * which basically is find smile OR simely OR grin OR joy 
 * between : and :
 */

var ele = document.getElementById("#whateverElement");
var result = ele.innerText.replace(regex,function(fullmatch,match){
   //fullmatch will be like :smile:
   //while match will be like smile, so you would want to use match in the class

   //Using a simple jquery call to create the span 
   //you could also just use string concatenation 
   var span = jQuery("<span>",{ class: "emoji "+match });

   //return the text you want to replace fullmatch with        
   return span[0].outerHTML;
});

ele.innerHTML = result;

Demo

var emojies = ["smile", "smiley", "grin", "joy"];
var regex = new RegExp(":("+ emojies.join("|") +"):","g");
var ele = document.getElementById("someDiv");
var result = ele.innerText.replace(regex,function(fullmatch,match){
   var span = jQuery("<span>",{ class: "emoji "+match });
   return span[0].outerHTML;
});
ele.innerHTML = result;
.emoji {
  display:inline-block;
  height:32px;
  width:32px;
  background-size:cover !important;
}
.emoji.joy {
  background: url(http://pix.iemoji.com/images/emoji/apple/8.3/256/face-with-tears-of-joy.png) no-repeat 0 0;
}

.emoji.grin {
  background: url(http://pix.iemoji.com/images/emoji/apple/8.3/256/grinning-face.png) no-repeat 0 0;
}

.emoji.smile {
  background: url(http://pix.iemoji.com/images/emoji/apple/8.3/256/smiling-face-with-open-mouth-and-smiling-eyes.png) no-repeat 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="someDiv">
   This is an example :smile:, of some text :grin: :joy: :joy:  
</div>

if you want it in a single function just put the replace call in the function and return the result

var emojies = ["smile", "smiley", "grin", "joy"];
var emojiRegex = new RegExp(":("+ emojies.join("|") +"):","g");

function stringToEmoji(text){
   //stealing sln's answer to make this shorter
   return text.replace(emojiRegex, '<span class="emoji $1"></span>');
}

as a jQuery function

(function($){
   var emojies = ["smile", "smiley", "grin", "joy"];
   var emojiRegex = new RegExp(":("+ emojies.join("|") +"):","g");
   $.fn.toEmoji = function(){
        return this.each(function() {
            this.innerHTML = this.innerText.replace(emojiRegex,function(fullmatch,match){
                return '<span class="emoji '+match.toLowerCase()+'"></span>';
            });                
        });
   };
})(jQuery);
//And use like
$(document).ready(function(){
    $(".content div").toEmoji();
});

JQuery function demo

(function($){
   var emojies = ["smile", "smiley", "grin", "joy"];
   var emojiRegex = new RegExp(":("+ emojies.join("|") +"):","g");
   $.fn.toEmoji = function(){
        return this.each(function() {
            this.innerHTML = this.innerText.replace(emojiRegex,function(fullmatch,match){
                return '<span class="emoji '+match.toLowerCase()+'"></span>';
            });                
        });
   };
})(jQuery);
//And use like
$(".content div.addemoji").toEmoji();
.emoji {
  display:inline-block;
  height:32px;
  width:32px;
  background-size:cover !important;
}
.emoji.joy {
  background: url(http://pix.iemoji.com/images/emoji/apple/8.3/256/face-with-tears-of-joy.png) no-repeat 0 0;
}

.emoji.grin {
  background: url(http://pix.iemoji.com/images/emoji/apple/8.3/256/grinning-face.png) no-repeat 0 0;
}

.emoji.smile {
  background: url(http://pix.iemoji.com/images/emoji/apple/8.3/256/smiling-face-with-open-mouth-and-smiling-eyes.png) no-repeat 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="content">
  <div class="addemoji">Some :grin: text :joy:</div>
  Content text
  <div class="addemoji">More :smile: text :joy:</div>
  even more content text
  <div class="addemoji">Yet some other :joy: text :grin:</div>
</div>
Patrick Evans
  • 41,991
  • 6
  • 74
  • 87
  • 1
    @PatrickEvans Is there something we can do about the case sensitivity? I mean, for this to work even if the case is different. If we use `"gi"` then there might be the css issues. – rrk Jun 12 '15 at 20:55
  • 1
    @Igor, you would need to do: `var result = stringToEmoji(test); $(".context").html( result );`, and as for the sensitivity yea use `gi`, and just use toLowerCase on the html before returning it – Patrick Evans Jun 12 '15 at 21:17
  • Thats okay! And can i use this function inside the `$(document).ready(function...`? – Igor Jun 12 '15 at 21:51
  • @Igor, fixed. And yes you could, just make sure the function creation part is before the ready, and then do the `$(".content div").toEmoji()` inside the ready. – Patrick Evans Jun 12 '15 at 21:54
3

Seems like a simple
text.replace(/:(smile|smiley|grin|joy):/g, '<span class=\'emoji $1\'></span>');
should do it.

  • I doubt it, tried it on `:smile: :smiley: :grin: :joy:`, I got was ` `. But this is a part of the solution. – rrk Jun 12 '15 at 20:39
  • 1
    @sln replace the `\1` with `$1`, +1 though for the shorter replace forgot you could do that :) – Patrick Evans Jun 12 '15 at 20:40
2

Loop through all the array items, and replace all using Regex. Then put the string inside the container.

My function

function stringToEmoji(text){
    var findText = '',
        htmlString = '';
    $.each(emojies, function(i, _this){
        findText=new RegExp(':'+$.trim(_this)+':','i');//need to add 'gi' to work properly
        htmlString = text.replace(findText,"<span class='emoji " + _this + "emoji_name'></span>")
    })
    return htmlString;
}

Improved using Patrick's answer

function stringToEmoji(text){
    var findText = '',
        htmlString = '',
        regex = new RegExp(":("+ emojies.join("|") +"):","gi");
    htmlString = text.replace(regex,"<span class='emoji $1'></span>");
    return htmlString;
}
rrk
  • 15,677
  • 4
  • 29
  • 45