使替换函数不区分大小写

4
我有一个用于将文本表情符号替换成图片表情符号的函数。
如何使此函数不区分大小写? 我已尝试在替换器中使用"gi"和"ig",但似乎没有任何效果。
var emots = {
    ':)' : 'smile',
    ':-)' : 'smile',
    ';)' : 'wink',
    ';-)' : 'wink',
    ':(' : 'downer',
    ':-(' : 'downer',
    ':D' : 'happy',
    ':-D' : 'happy',
    '(smoke)' : 'smoke',
    '(y)' : 'thumbsup',
    '(b)' : 'beer',
    '(c)' : 'coffee',
    '(cool)' : 'cool',
    '(hehe)' : 'tooth',
    '(haha)' : 'tooth',
    '(lol)' : 'tooth',
    '(pacman)' : 'pacman',
    '(hmm)' : 'sarcastic',
    '(woot)' : 'woot',
    '(pirate)' : 'pirate',
    '(wtf)' : 'wtf'
};

function smile(str){
    var out = str;
        for(k in emots){
            out = out.replace(k,'<img src="/emoticons/'+emots[k]+'.gif" title="'+k+'" />','g');
        }
    return out;
};

据我所见,“i”仅在Firefox中有效。 - mowgli
3个回答

2

变更:

out = out.replace(k,'<img src="/emoticons/'+emots[k]+'.gif" title="'+k+'" />','g');

致:

out = out.replace(new RegExp(k.replace(/[-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), 'ig'), '<img src="/emoticons/'+emots[k]+'.gif" title="'+k+'" />');

从这个答案中获取的正则表达式转义函数(Escape string for use in Javascript regex)


那个 for(k in emots){) 里面的内容是什么? - mowgli
@mowgli 是的,没错。它只是将你的替换函数中的标志取出并转化成正则表达式的标志。escapeRegExp 转义所有特殊的正则表达式字符,尽管你真正只需要对输入中的 () 进行转义,但最好对所有字符进行转义,以防你后来添加使用其他字符(如]:[)的新表情符号。 - Paul
好的,但是我在想... 在循环中创建一个函数不是错了吗?我猜它会被创建(或检查并且不会重新创建,我不确定)每个字母。 - mowgli
@mowgli 是的,抱歉。只有一行代码在循环中。我没有表达清楚。该函数只需在同一作用域中即可。紧跟在您的循环后面是一个好地方,或者您可以完全取消该函数。只需使用k.replace(/[-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")替换escapeRegExp(k)即可。 - Paul

1

这比表面上看起来要棘手一些。以下是一个完整的解决方案。为了简单高效,它仅在目标字符串上使用一个正则表达式搜索。

请注意,因为它是不区分大小写的(例如,(hehe)(HeHe)被视为相同),因此:-d也被视为与:-D相同。

var emots = {
    ':)' : 'smile',
    ':-)' : 'smile'
    // Add the rest of your emoticons...
};

// Build the regex that will be used for searches
var emotSearch = [];
for (var p in emots) {
    if (emots.hasOwnProperty(p)) {
        emotSearch.push(p.replace(/[-[{()*+?.\\^$|]/g, '\\$&'));
        if (p !== p.toLowerCase()) {
            emots[p.toLowerCase()] = emots[p];
        }
    }
}
emotSearch = RegExp(emotSearch.join('|'), 'gi');

function smile(str) {
    return str.replace(emotSearch, function ($0) {
        var emot = $0.toLowerCase();
        if (emot in emots) {
            return '<img src="/emoticons/' + emots[emot] + '.gif" title="' + $0 + '" />';
        }
        return $0;
    });
}

哇,好多代码啊... 没有尝试过。另一个更短的答案是完美的。而且简单就是好的 ;) - mowgli
就这样吧。不过,你要知道,其他你提到的答案需要为每个表情符号的属性进行单独搜索和替换,这样效率明显会降低,并且随着你添加更多的表情符号搜索将变得越来越慢。它还使用了一个不必要冗长的正则表达式来转义正则表达式元字符。 - slevithan

-2

或者在检查之前只需对输入使用.toLowerCase()?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接