为什么javascript正则表达式不';有些表情符号不匹配

为什么javascript正则表达式不';有些表情符号不匹配,javascript,regex,emoticons,Javascript,Regex,Emoticons,我实现了javascript函数,该函数匹配表情键组合,并用span和特定的css类替换它们 我确信我用所有支持的表情符号和所有替代品测试了这个系统,效果很好。但现在有些表情符号无法匹配,我也不明白为什么 例如,表情符号“:p”与我的正则表达式不匹配,但“:)”与之匹配 匹配和替换字符的功能是: /** * Replace combination of chars with emoticons * @param rawText string * @returns s

我实现了javascript函数,该函数匹配表情键组合,并用span和特定的css类替换它们

我确信我用所有支持的表情符号和所有替代品测试了这个系统,效果很好。但现在有些表情符号无法匹配,我也不明白为什么

例如,表情符号“:p”与我的正则表达式不匹配,但“:)”与之匹配

匹配和替换字符的功能是:

/**
     * 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]);
        });
    };
/**
*将字符组合替换为表情符号
*@param原始文本字符串
*@返回字符串
*@私人
*/
prototype.\u processemotics=函数(rawText){
变量fbEmoticonHolder='';
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':fMemoticonHolder.替换(':HOLDER:','geek'),
“:-P”:fbEmoticonHolder.replace(“:HOLDER:”,“tangle”),
“:P”:fbEmoticonHolder.replace(“:HOLDER:”,“Lange”),
“:-p”:fbEmoticonHolder.replace(“:HOLDER:”,“tangle”),
“:p”:fbEmoticonHolder.replace(“:HOLDER:”,“Lange”),
“=P”:fbEmoticonHolder.replace(“:HOLDER:”,“舌头”),
“=p”:fbEmoticonHolder.replace(“:HOLDER:”,“舌头”),
“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”),

“你应该避开你的表情符号。所以:)的正则表达式是:\)。否则(:)就是一个不平衡的正则表达式。

我解决了我的问题。 稍微修改一下正则表达式对我来说很好。如果javascript支持正则表达式lookbehinds,那会容易得多,但事实并非如此

所以我做了一点变通。我将在较小的示例上展示解决方案,因为完整的示例太大了

旧的正则表达式如下所示:

\B((?::\))|(?::P)|(?:XD))\B(?!\w)
该正则表达式应匹配:)或:p或XD,前面至少有一个空格字符或字符串的开头,后面至少有一个空格字符或字符串的结尾

这些条件很重要,因为我不想匹配如下内容:):)或asdf:)或:)asdf

它必须是清晰的表情符号

我更改了我的正则表达式,最后我使用了正前瞻而不是负前瞻,删除了\B作为匹配字符串的边界,并添加了在正则表达式开头模拟正前瞻的代码和平

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

现在一切看起来都很好。这个补丁将在早上开始制作,所以你可以尝试我们的facebook聊天(在facebook登录后),看看在这个伟大的音乐网络播放器(以及更多)上是否一切都正常。

我不明白。你能再详细一点吗?我想@mrhobo的意思是“所以:)的正则表达式是:\)”.这就是你的意思,不是吗?我想SO的评论过程去掉了一个反斜杠。正确。我写这个答案时正在乘地铁。我按回车键是因为我的车站在那里:)我已经更正了我的答案(^ |\W)((?::)|(?:)(?::P)(?:XD))(?=(\s |$)不是正确的正则表达式。看一看:你应该转义结束括号。它应该是(^ |\W)((?:\)|(?::P)|(?:XD))(?=(\s |$)是的,你是对的。我在我的真实代码中转义了它们,但在我的示例中也忘了转义。我将编辑我的答案。