Question

I implement javascript function which match emoticons key combinations and replace them with the span and particular css class.

I'm sure that I tested system with all supported emoticons and all replacements worked just fine. But now some of emoticon characters couldn't be matched and I can't figure out why.

For ex. emoticon ':P' isn't matched with my regex but ':)' it is.

The function for matching and replacing characters is:

/**
     * Replace combination of chars with emoticons
     * @param rawText string
     * @returns string
     * @private
     */

    chatWindow.prototype._processEmoticons = function(rawText) {
        var fbEmoticonHolder = '<span class="emoticon :HOLDER:"></span>';

        var replacementMap = {
            ':)' : fbEmoticonHolder.replace(':HOLDER:', 'smile'),
            ':-)' : fbEmoticonHolder.replace(':HOLDER:', 'smile'),
            ':(' : fbEmoticonHolder.replace(':HOLDER:', 'sad'),
            ':-(' : fbEmoticonHolder.replace(':HOLDER:', 'sad'),
            '8-)' : fbEmoticonHolder.replace(':HOLDER:', 'geek'),
            '8)' : fbEmoticonHolder.replace(':HOLDER:', 'geek'),
            'B-)' : fbEmoticonHolder.replace(':HOLDER:', 'geek'),
            'B)' : fbEmoticonHolder.replace(':HOLDER:', 'geek'),
            ':-P' : fbEmoticonHolder.replace(':HOLDER:', 'tongue'),
            ':P' : fbEmoticonHolder.replace(':HOLDER:', 'tongue'),
            ':-p' : fbEmoticonHolder.replace(':HOLDER:', 'tongue'),
            ':p' : fbEmoticonHolder.replace(':HOLDER:', 'tongue'),
            '=P' : fbEmoticonHolder.replace(':HOLDER:', 'tongue'),
            '=p' : fbEmoticonHolder.replace(':HOLDER:', 'tongue'),
            'o.O' : fbEmoticonHolder.replace(':HOLDER:', 'speechless'),
            'O.o' : fbEmoticonHolder.replace(':HOLDER:', 'speechless'),
            ':v' : fbEmoticonHolder.replace(':HOLDER:', 'pacman'),
            'O:)' : fbEmoticonHolder.replace(':HOLDER:', 'angel'),
            'O:-)' :  fbEmoticonHolder.replace(':HOLDER:', 'angel'),
            '<3' : fbEmoticonHolder.replace(':HOLDER:', 'heart'),
            ':\'(' : fbEmoticonHolder.replace(':HOLDER:', 'cry'),
            ':-D' : fbEmoticonHolder.replace(':HOLDER:', 'laugh'),
            ':D' : fbEmoticonHolder.replace(':HOLDER:', 'laugh'),
            '=D' : fbEmoticonHolder.replace(':HOLDER:', 'laugh'),
            '8-|' : fbEmoticonHolder.replace(':HOLDER:', 'cool'),
            '8|' : fbEmoticonHolder.replace(':HOLDER:', 'cool'),
            'B-|' : fbEmoticonHolder.replace(':HOLDER:', 'cool'),
            'B|' : fbEmoticonHolder.replace(':HOLDER:', 'cool'),
            ';-)' : fbEmoticonHolder.replace(':HOLDER:', 'wink'),
            ';)' : fbEmoticonHolder.replace(':HOLDER:', 'wink'),
            ':-&' : fbEmoticonHolder.replace(':HOLDER:', 'sick'),
            ':&' : fbEmoticonHolder.replace(':HOLDER:', 'sick'),
            ':-O' : fbEmoticonHolder.replace(':HOLDER:', 'shock'),
            ':O' : fbEmoticonHolder.replace(':HOLDER:', 'shock'),
            ':-o' : fbEmoticonHolder.replace(':HOLDER:', 'shock'),
            ':o' : fbEmoticonHolder.replace(':HOLDER:', 'shock'),
            '3:)' : fbEmoticonHolder.replace(':HOLDER:', 'devil'),
            '3:-)' : fbEmoticonHolder.replace(':HOLDER:', 'devil'),
            ':-/' : fbEmoticonHolder.replace(':HOLDER:', 'mixed'),
            ':/' : fbEmoticonHolder.replace(':HOLDER:', 'mixed'),
            ':-\\' : fbEmoticonHolder.replace(':HOLDER:', 'mixed'),
            ':\\' : fbEmoticonHolder.replace(':HOLDER:', 'mixed'),
            '[[f9.rainbow]]' : fbEmoticonHolder.replace(':HOLDER:', 'rainbow'),
            '[[f9.cake]]' : fbEmoticonHolder.replace(':HOLDER:', 'cake'),
            '[[f9.coffee]]' : fbEmoticonHolder.replace(':HOLDER:', 'coffee'),
            '[[f9.gift]]' : fbEmoticonHolder.replace(':HOLDER:', 'gift'),
            '[[f9.bomb]]' : fbEmoticonHolder.replace(':HOLDER:', 'bomb'),
            '[[f9.clap]]' : fbEmoticonHolder.replace(':HOLDER:', 'clap'),
            '[[f9.sleepy]]' : fbEmoticonHolder.replace(':HOLDER:', 'sleepy'),
            '[[f9.stary]]' : fbEmoticonHolder.replace(':HOLDER:', 'stary'),
            '[[f9.heartbreak]]' : fbEmoticonHolder.replace(':HOLDER:', 'heartbreak'),
            '[[f9.inlove]]' : fbEmoticonHolder.replace(':HOLDER:', 'inlove')
        };

        var charsForReplacement = [
            ':\\)', ':-\\)', ':\\(', ':-\\(', '8-\\)', '8\\)', 'B-\\)', 'B\\)', ':-P', ':P', ':-p', ':p', '=P', '=p', 'o.O',
            'O.o', ':v', 'O:\\)', 'O:-\\)', '<3', ':\'\\(', ':-D', ':D', '=D', '8-\\|', '8\\|', 'B-\\|', 'B\\|', ';-\\)',
            ';\\)', ':-&', ':&', ':-O', ':O', ':-o', ':o', '3:\\)', '3:-\\)', ':-/', ':/', ':-\\\\', ':\\\\',
            '\\[\\[f9.rainbow\\]\\]', '\\[\\[f9.cake\\]\\]', '\\[\\[f9.coffee\\]\\]', '\\[\\[f9.gift\\]\\]',
            '\\[\\[f9.bomb\\]\\]', '\\[\\[f9.clap\\]\\]', '\\[\\[f9.sleepy\\]\\]', '\\[\\[f9.stary\\]\\]',
            '\\[\\[f9.heartbreak\\]\\]', '\\[\\[f9.inlove\\]\\]'
        ];

        /*
         FOR TESTING PURPOSES (paste it in the chat window)

         :) :-) :( :-(
         8-) 8) B-) B) :-P :P :-p :p =P =p o.O O.o :v O:)
         O:-) <3 :'( :-D :D =D 8-| 8| B-| B| ;-) ;) :-& :& :-O :O :-o :o 3:) 3:-) :-/ :/ :-\ :\
         [[f9.rainbow]] [[f9.cake]] [[f9.coffee]] [[f9.gift]] [[f9.bomb]] [[f9.clap]] [[f9.sleepy]] [[f9.stary]] [[f9.heartbreak]] [[f9.inlove]]
         */

        // generate regex - START
        var regexPattern = '\\B(';

        for (var i in charsForReplacement) {
            regexPattern += '(?:' + charsForReplacement[i] + ')';

            if (i != charsForReplacement.length - 1) {
                regexPattern += '|';
            }
        }

        regexPattern += ')\\B(?!\\w)';
        // generate regex - END

        var regex = new RegExp(regexPattern, 'g');

        return rawText.replace(regex, function(match) {

            var replacement = $.trim(match);

            return match.replace(replacement, replacementMap[replacement]);
        });
    };

What I'm trying to do is create regular expression for matching all emoticons. Array charsForReplacement is used to create regular exp. pattern because emoticons sometimes have characters which are special characters in regular expression patterns.

replacementMap is used when emoticn is matched then read with what it needs to be replaced.

Generated reg. exp. pattern is:

\B((?::))|(?::-))|(?::()|(?::-()|(?:8-))|(?:8))|(?:B-))|(?:B))|(?::-P)|(?::P)|(?::-p)|(?::p)|(?:=P)|(?:=p)|(?:o.O)|(?:O.o)|(?::v)|(?:O:))|(?:O:-))|(?:<3)|(?::'()|(?::-D)|(?::D)|(?:=D)|(?:8-\|)|(?:8\|)|(?:B-\|)|(?:B\|)|(?:;-))|(?:;))|(?::-&)|(?::&)|(?::-O)|(?::O)|(?::-o)|(?::o)|(?:3:))|(?:3:-))|(?::-/)|(?::/)|(?::-\)|(?::\)|(?:[[f9.rainbow]])|(?:[[f9.cake]])|(?:[[f9.coffee]])|(?:[[f9.gift]])|(?:[[f9.bomb]])|(?:[[f9.clap]])|(?:[[f9.sleepy]])|(?:[[f9.stary]])|(?:[[f9.heartbreak]])|(?:[[f9.inlove]]))\B(?!\w)

But it seems complicated but it's really not. That is because there is a lot of emoticons that could be matched.

BUt let say for example that we want to match just a few emoticons, e.g. ':)', ':P', 'XD' Then reg. exp. pattern would look like:

\B((?::))|(?::P)|(?:XD))\B(?!\w)

I need your help folks!

Était-ce utile?

La solution 2

I solved my problem. Changing regex a little bit works fine for me. It would be lot easier if javascript support regex lookbehinds, but it doesn't.

So I made a little workaround. I'll show solution on smaller example because full example is too big.

Old regular expression looks like:

\B((?::\))|(?::P)|(?:XD))\B(?!\w)

That regex should match :) or :P or XD preceded by at least one whitespace character or by begining of the string, and followed by at least one whitespace character or end of the string.

Those conditions are important because I don't want to match something like this :):) or asdf:) or :)asdf

It must be clear emoticon.

I've change my regex, at the end I use positive lookahead instead of negative lookahead, removed \B as a boundaries of my matching string and add peace of code which simulates positive lookbehind at the begining of the regex.

(^|\W)((?::\))|(?::P)|(?:XD))(?=(\s|$))

Now everything looks fine. This fix will be on production http://starvibes.com right in the morning so you can try our facebook chat (after facebook login) and see if everithing works fine on this great music web player (and much much more).

Autres conseils

You should escape your emoticons. So the regex for :) is :\). Otherwise (::)) is an unbalanced regex.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top