JavaScript正则表达式匹配我的数组中的表情符号

3
我有一个包含emo符号和每个符号对应的图像文件路径的数组。
但是,使用这段代码,只有 :) 这个符号才能返回正确的smile.png图像,其他的emo没有起作用。
我该如何编写正确的正则表达式来匹配每个符号并为每个emo选择适当的文件? 在JSFIDDLE上查看我的代码演示
 //Replace Emo with images
  function replaceEmoticons(text) {
  var emoticons = {
    ':)' : 'smile.png',
    ': )' : 'smile.png',
    ':D' : 'laugh.png',
    ':->' : 'laugh.png',
    ':d' : 'laugh-sm.png',
    ':-)': 'smile-simple.png',
    ':p': 'tounge.png',
    ':P': 'tounge-lg.png',
    ': P': 'tng1.png',
    '>-)': 'evil.png',
    ':(': 'sad.png',
    ':-(': 'sadd.png',
    ':-<': 'sadd.png',
    ':-O': 'surprise.png',
    ':O': 'sur2.png',
    ':o': 'sur3.png',
    ':-o': 'sur3.png',
    ':-*': 'kiss.png',
    ':*': 'kiss.png',
    ':-@': 'angry.png',
    ':@': 'angry.png',
    ':$': 'con2.png',
    ':-$': 'con1.png',
    'O.o': 'con2.png',
    'o.O': 'con2.png',
    ':/': 'weird.png',
    ':x': 'x.png',
    ':X': 'x.png',
    ':!': 's.png',
    '(:I': 'egg.png',
    '^.^': 'kit.png',
    '^_^': 'kit.png',
    ';)': 'wink.png',
    ';-)': 'wink.png',
    ":')": 'hc.png',
    ":'(": 'cry.png',
    "|-O": 'yawn.png',
    "-_-": 'poke.png',
    ":|": 'p1.png',
    "$_$": 'he.png'

  }, url = "images/emo/";
  // a simple regex to match the characters used in the emoticons
  return text.replace(/[:\-)D]+/g, function (match) {

    return typeof emoticons[match] != 'undefined' ?
           '<img class="emo" src="'+url+emoticons[match]+'"/>' :
           match;
  });
}


replaceEmoticons("Hi this is a test string :) with all :P emos working :D");

1
请查看以下链接,了解有关正则表达式匹配表情符号的问题:https://dev59.com/eofca4cB1Zd3GeqPeiDlhttp://stackoverflow.com/questions/7317299/regex-matching-list-of-emoticons-of-various-type - Tim007
1个回答

2
这个正则表达式:
 [:\-)D]+

不匹配列表中的许多表情符号。除了:\-)D之外的任何字符都会防止其被识别。

如果您有一个要匹配的字符串列表,可以通过转义每个字符串并使用|将它们连接在一起来轻松构建正则表达式以匹配其中任何一个(而仅仅是它们)。像这样:

// given a string, return the source for a regular expression that will 
// match only that exact string, by escaping any regex metacharacters
// contained within.
RegExp.escape = function(text) {
  return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}

// build a regex that will match all the emoticons. Written out, it looks
// like this:   /:\)|: \)|:D|:->|:d|:-\)|:p|:P|..../g
var emoticonRegex = 
  new RegExp(Object.keys(emoticons).map(RegExp.escape).join('|'), 'g');

然后使用它来代替您的字面正则表达式:
return text.replace(emoticonRegex, function (match) { ...

但是 OP 怎么编写正则表达式呢?(我相信这就是 OP 提出的问题)。 - random_user_name
我正要讲到那部分,@cale_b. :) - Mark Reed
好的,我已经成功将所有表情符号写入我的字符串中,似乎已经可以正常工作了。能否有人向我解释一下正则表达式是如何工作的?它会考虑每个字符组合吗?这段代码对我来说可行,只是我不明白它的工作原理。text.replace(/[:;-)DPp(oO|><*!']+/g, function (match) - Faizan
谢谢,但我只是在我的正则表达式中使用每个字符的单一出现而没有转义或使用管道符号连接任何内容,这似乎也可以工作。我的方法有其他不良影响吗?它会将简单的文本消息视为表情符号吗?还是我可以安全地使用我的方法?对我来说,这种方法可行。返回 text.replace(/[:^;-)DPp(oO|><*!'-@._d]+/g, function (match) { - Faizan
你的解决方案匹配了所有表情符号,但它也会匹配那些列表中没有出现的字符组合 - 例如,任意数量的冒号、连字符或句点:::---...都可以匹配。甚至一个句子中的单个括号也会匹配。当它找到一个在表格中没有条目的匹配项时,它将用 src="undefined"<img> 标签替换它。 - Mark Reed

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