0
\$\begingroup\$

This function's job is to replace several text smilies, e.g. :D, :), :love with the appropriate smiley image. In my opinion my code has several issues, yet the main problem is that a lot of quite similar regexes are created dynamically: one for each different smilie replaced. As you might expect, replacing smilies in a text is a job done kindly often, so this is indeed code that is executed a lot of time, therefore I think optimizing that makes sense.

Well, why didn't I just call text.replace()? I don't want the smilies to be replaced if they are enclosed by backticks: `

var replaceTextSmilies = function() {
    var smiliesShortcut = {};
    smiliesShortcut[':)'] = 'smile.png';
    /* adding much more */

    var smiliesWordy = {};
    smiliesWordy[':angry'] = 'angry.png';
    /* adding much more */



    function escapeRegExp(str) {
        return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
    }

    return function(text) {
        Object.keys(smiliesWordy).forEach(function(entry) {
            var image = '<img src="img/smilies/' + smiliesWordy[entry] + '"/>';

            if(text.indexOf(entry) !== -1) {
                var regex = new RegExp('('+ escapeRegExp(entry) +')(?=(?:(?:[^`]*`){2})*[^`]*$)', 'g');
                text = text.replace(regex, image);
            }
        });
        Object.keys(smiliesShortcut).forEach(function(entry) {
            var image = '<img src="img/smilies/' + smiliesShortcut[entry] + '"/>';

            if(text.indexOf(entry) !== -1) {
                var regex = new RegExp('('+ escapeRegExp(entry) +')(?=(?:(?:[^`]*`){2})*[^`]*$)', 'g');
                text = text.replace(regex, image);
            }
        });
        return text;
    };
}();
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You can store the regex as part of the smily metadata.

var replaceTextSmilies = function() {
    var smiliesShortcut = {};
    smiliesShortcut[':)'] = {
        img : 'smile.png'
    };
    /* adding much more */

    var smiliesWordy = {};
    smiliesWordy[':angry'] = {
        img : 'angry.png'
    };
    /* adding much more */

    addRegex(smiliesShortcut);
    addRegex(smiliesWordy);

    function escapeRegExp(str) {
        return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
    }

    function addRegex(smilies) {
        Object.keys(smilies).forEach(function(smily) {
            smilies[smily].regex = new RegExp('(' + escapeRegExp(smily) + ')(?=(?:(?:[^`]*`){2})*[^`]*$)', 'g');
        });
    }

    function replace(text, smilies) {
        Object.keys(smilies).forEach(function(entry) {
            var image = '<img src="img/smilies/' + smilies[entry].img + '"/>';

            if (text.indexOf(entry) !== -1) {
                text = text.replace(smilies[entry].regex, image);
            }
        });
        return text;
    }

    return function(text) {
        text = replace(text, smiliesWordy);
        text = replace(text, smiliesShortcut);
        return text;
    };
}();

Demo: Fiddle

Note: You can make it even better if you can manually create the regex and assign them instead of using addRegex() like

    smiliesShortcut[':)'] = {
        img : 'smile.png',
        regex: /<the regex>/
    };
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.