为不匹配包含字母的表情符号的表情符号使用 \B 实施 RegExp

Implementing RegExp with \B for emoticons not matching for emoticons containing letters

我正在为一个游戏项目开发一个聊天客户端,并且正在实现表情符号。表情符号在聊天中显示位置的基本规则是,当它们紧挨着文本时,它们不会出现。

我创建了正则表达式:\B(emoticontext)\B.

不幸的是,我遇到了一个问题,它对除了包含字母的表情符号之外的每个表情符号都非常有效。 (例如:D、O_o 等)

我不知道该如何补救。

function parseEmoticons(text) {
    var pattern;
    emoticons.forEach(function (emoticon) {
        pattern = new RegExp("\B" + emoticon.string + "\B", 'g');
        text = text.replace(pattern, emoticon.img);
    });
    return text;
}

这是表情符号数组的一部分,用于上下文。

  { 'string': ':\)', 'img': '<img src="' + imgpath + 'emoticons/smile.png" class="emoticon"/>' },
    { 'string': ':O', 'img': '<img src="' + imgpath + 'emoticons/surprised.png" class="emoticon"/>' },
    { 'string': ':D', 'img': '<img src="' + imgpath + 'emoticons/happy.png" class="emoticon"/>' },

do not appear when they are directly next to text

这听起来更像是您想检查周围的白色space,而不是 \B("non-word-boundary")。

即:

var pattern = new RegExp('(^|\s)' + emoticon.string.replace(/\W/g, '\$&') + '(?!\S)', 'g');
text = text.replace(pattern, function (m0, m1) { return m1 + emoticon.img; });

注意事项:

  • (^|\s) 检查(并捕获)字符串的开头或白色space 字符
  • .replace(/\W/g, '\$&') 转义表情符号中所有潜在的正则表达式元字符(这意味着您可能必须将表情符号列表中的 ':\)' 更改为 ':)'
  • (?!\S) ("not followed by a non-space character") 确保表情符号后跟白色 space 或字符串结尾(我们不能在开头使用相同的技巧,因为JavaScript 不支持后视)
  • 因为我们可能在开头捕获了一个 space 字符,所以我们必须将它与我们的 HTML 代码一起替换回去
  • 我们可以用 .replace(pattern, '' + emoticon.img) 做到这一点,但如果 emoticon.img 最终包含 .replace 理解和解释的特殊 $ 模式之一,那将导致问题
  • 相反,我们使用替换函数,它将整个匹配的字符串和捕获组(以及其他一些东西)作为参数(但我们只关心第一个捕获组)