如何使用JavaScript删除表情符号代码?

67

如何使用JavaScript删除表情符号代码?我认为我已经使用下面的代码解决了这个问题,但我仍然有像 这样的字符。

function removeInvalidChars() {
    return this.replace(/[\uE000-\uF8FF]/g, '');
}

1
那个范围内有很多字符 - 也许你应该删除你不喜欢的单个代码点? - sarnold
2
我认为https://dev59.com/tG865IYBdhLWcg3wlviq可以回答你的问题。 - Jonathan Protzenko
1
这是一篇很好的文章,也涉及到这些范围:http://crocodillon.com/blog/parsing-emoji-unicode-in-javascript - acme
20个回答

107

对我来说,没有一个答案完全可以去除所有的表情符号,所以我不得不自己动手解决,这就是我得到的:

text.replace(/([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g, '');

同时,需要考虑到如果将该字符串插入数据库后,用空字符串替换可能会导致安全问题。建议使用替换字符U+FFFD进行替换。详情请参见:http://www.unicode.org/reports/tr36/#Deletion_of_Noncharacters


4
尝试了许多解决方案,但这一个很成功!对于任何使用 Twitter API 的人,我有一点建议 - 这个方法适用于我! - Simon G
13
这涵盖了相当广泛的范围,但我必须进行一些编辑以涵盖一些遗漏的内容。具体来说,我将现有字符集 [\u2694-\u2697] 扩展到 [\u2580-\u27BF],以包括一些其他的形状和饰品,这样就可以匹配常见的 ❤️ 字符 (\u2764\uFE0F)。我还将 \uD83E[\uDD10-\uDD5D] 扩展到 \uD83E[\uDD10-\uDDFF],以捕捉一些表情符号,如,,,,和。 - Caleb Miller
1
@CalebMiller,你能否发布你的最终正则表达式? - avalanche1
3
嗨 @avalanche1,是的,这就是我使用的正则表达式,我最终还进行了额外的改进:/[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2580-\u27BF]|\uD83E[\uDD10-\uDDFF]/g - Caleb Miller
1
\g之前添加|,它也会处理任何空格。如果有人需要:/[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2580-\u27BF]|\uD83E[\uDD10-\uDDFF]| /g - PRO
显示剩余3条评论

66
您选择的范围是专用区,包含非标准字符。运营商以前在此范围内使用不同、不一致的编码来编码表情符号。
最近,这些表情符号已被赋予了标准化的“统一”代码点。其中许多位于基本多文种平面之外,在区块U+1F300-U+1F5FF中,包括您举的例子U+1F534大红色圆圈。
您可以在支持非BMP字符的正则表达式引擎中使用[\U0001F300-\U0001F5FF]来检测这些字符,但JavaScript的RegExp不支持这样的操作。不幸的是,JS字符串模型是基于UTF-16码元构建的,因此您需要在正则表达式中使用UTF-16代理。
return this.replace(/([\uE000-\uF8FF]|\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDDFF])/g, '')

需要注意的是,基本多语言平面中还有其他一些字符被手机用作表情符号,但这些字符在表情符号出现之前就存在了。例如,U+2665是传统的红心花色字符♥,但在某些设备上它可能被呈现为表情符号图形。你可以选择将其视为表情符号并尝试将其删除。请参见此列表以获取更多示例。


1
此外,应考虑到如果稍后将字符串插入数据库,用空字符串替换可能会暴露安全问题。而应该使用替换字符 U+FFFD 进行替换,参见:http://unicode.org/reports/tr36/#Deletion_of_Noncharacters。 - jony89
你如何处理包含多个码点的表情符号,例如警告表情符号?该表情符号使用U+26A0后跟U+FE0F。你的正则表达式将保留第二个码点不变。 - Sebastian

50

我使用正则表达式和Unicode属性转义来解决了它。我从这篇文章中得到的,虽然是针对Java的,但仍然非常有用 - 从Java字符串中删除表情符号

'Smile'.replace(/[^\p{L}\p{N}\p{P}\p{Z}^$\n]/gu, '');

它会删除除以下符号外的所有符号:

  • \p{L} - 任何语言的所有字母
  • \p{N} - 数字
  • \p{P} - 标点符号
  • \p{Z} - 空格分隔符
  • ^$\n - 添加您想要保留的任何符号

这个方法更加正确,也能起作用,但是对于我来说会在字符串中留下一些垃圾符号:

    'Smile'.replace(/\p{Emoji}/gu, '');
编辑:添加了评论中的符号

那非常优雅。 - avalanche1
不幸的是,它删除了 ^$。 应该是 /[^\p{L}\p{N}\p{P}\p{Z}{\^\$}]/gu - avalanche1
在复杂表情符号的情况下。例如:'‍'.replace(/\p{Emoji}/gu, '').charCodeAt(0) - hababr
3
我测试了 /\p{Emoji}/gu,它会移除数字。 "Test123" 变成了 "Test" - vozaldi
1
@hababr 省了我很多时间。谢谢 :) - undefined
显示剩余4条评论

22

我找到了很多建议,但解决我的问题的正则表达式是:

/(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g

一个简短的例子

function removeEmojis (string) {
  var regex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g;
  return string.replace(regex, '');
}

希望它能够帮助你


1
对我来说是个很好的答案。然而,正则表达式中的一个错误也导致它匹配了右括号([)。看起来只是复制和粘贴代码时出现了错误,但是Lucas请修复一下。修正后的正则表达式在这里:https://pastebin.com/0VZZKfWf - Marc Guiselin
感谢您的建议,@MarcGuiselin。 - lucas
我会在给定的正则表达式中添加 [\u200d] 和 [\ufe0f]。它们都是特殊字符,有助于创建表情符号序列。如果您仅使用上面的正则表达式来删除表情符号,则您的文本将包含大量这些空格字符。请参见 https://evgenyzborovsky.com/2018/04/07/the-ultimate-guide-to-emojis/。 - Martin Brabec

14

仅是对 @hababr 回答的补充。

如果您需要去除复杂的表情符号,您还必须删除诸如修饰符等其他内容:

'‍'.replace(/[\p{Emoji}\p{Emoji_Modifier}\p{Emoji_Component}\p{Emoji_Modifier_Base}\p{Emoji_Presentation}]/gu, '').charCodeAt(0)

更新:

*#0-9 - 是带有默认文本表示的表情符号,符合 Unicode 标准。

因此,我的当前解决方案如下:

'‍'.replace(/(?![*#0-9]+)[\p{Emoji}\p{Emoji_Modifier}\p{Emoji_Component}\p{Emoji_Modifier_Base}\p{Emoji_Presentation}]/gu, '').charCodeAt(0)

4
截至2022年,这似乎是最佳答案。 - gustavopch

6

@bobince的解决方法对我没起作用,要么表情符号还在原地,要么被其他表情符号替换了。

这个解决方法对我很有帮助:

var ranges = [
  '\ud83c[\udf00-\udfff]', // U+1F300 to U+1F3FF
  '\ud83d[\udc00-\ude4f]', // U+1F400 to U+1F64F
  '\ud83d[\ude80-\udeff]' // U+1F680 to U+1F6FF
];


$('#mybtn').on('click', function() {
  removeInvalidChars();
})

function removeInvalidChars() {
  var str = $('#myinput').val();

  str = str.replace(new RegExp(ranges.join('|'), 'g'), '');
  $("#myinput").val(str);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="myinput"/>
<input type="submit" id="mybtn" value="clear"/>

Source


4
这个解决方案对许多字符也不起作用。 - Meysam
我输入了所有的表情符号列表。但是有些被清除了,结果是这样的 = ✌‍♂️‍♀️❤‍♀️‍♂️‍‍‍‍‍‍✔✨ - Thameem

6

我知道这篇文章有点旧,但我在工作中遇到了这个问题,我的同事提出了一个有趣的想法。基本上,不要剥离表情符号字符,只允许有效的字符存在。可以参考这个 ASCII 表:

http://www.asciitable.com/

像下面这样的函数只会保留合法字符(范围取决于你所需要的内容)。

function (input) {
            var result = '';
            if (input.length == 0)
                return input;
            for (var indexOfInput = 0, lengthOfInput = input.length; indexOfInput < lengthOfInput; indexOfInput++) {
                var charAtSpecificIndex = input[indexOfInput].charCodeAt(0);
                if ((32 <= charAtSpecificIndex) && (charAtSpecificIndex <= 126)) {
                    result += input[indexOfInput];
                }
            }
            return result;
        };

这应该保留字母表中的所有数字,字母和特殊字符,适用于您希望保留英文字母+数字+特殊字符的情况。希望能对某些人有所帮助 :)

好的。不过我会添加新行和回车符(ASCII 10和13)。 - Boris Gafurov
1
如果我需要保留特定于语言环境的字符,例如西里尔字母、希伯来文等,该怎么办? - avalanche1

5

在搜索和尝试了许多Unicode正则表达式后,我建议您尝试这个,它可以涵盖所有的表情符号

function removeEmoji(str) {
  let strCopy = str;
  const emojiKeycapRegex = /[\u0023-\u0039]\ufe0f?\u20e3/g;
  const emojiRegex = /\p{Extended_Pictographic}/gu;
  const emojiComponentRegex = /\p{Emoji_Component}/gu;
  if (emojiKeycapRegex.test(strCopy)) {
    strCopy = strCopy.replace(emojiKeycapRegex, '');
  }
  if (emojiRegex.test(strCopy)) {
    strCopy = strCopy.replace(emojiRegex, '');
  }
  if (emojiComponentRegex.test(strCopy)) {
    // eslint-disable-next-line no-restricted-syntax
    for (const emoji of (strCopy.match(emojiComponentRegex) || [])) {
      if (/[\d|*|#]/.test(emoji)) {
        continue;
      }
      strCopy = strCopy.replace(emoji, '');
    }
  }

  return strCopy;
}
let a = "1️⃣aa‍♂️b#️⃣✅❎23#!^*bb‍♀️ccc";
console.log(removeEmoji(a))

参考:Unicode Emoji文档


4

这里的所有答案都不能处理我测试过的所有Unicode字符(特别是杂项范围内的字符,例如⛽或☯️)。

以下是适用于我个人情况的一种方法,灵感(很大程度上)来自这个PHP SO答案

function _removeEmojis(str) {
  return str.replace(/([#0-9]\u20E3)|[\xA9\xAE\u203C\u2047-\u2049\u2122\u2139\u3030\u303D\u3297\u3299][\uFE00-\uFEFF]?|[\u2190-\u21FF][\uFE00-\uFEFF]?|[\u2300-\u23FF][\uFE00-\uFEFF]?|[\u2460-\u24FF][\uFE00-\uFEFF]?|[\u25A0-\u25FF][\uFE00-\uFEFF]?|[\u2600-\u27BF][\uFE00-\uFEFF]?|[\u2900-\u297F][\uFE00-\uFEFF]?|[\u2B00-\u2BF0][\uFE00-\uFEFF]?|(?:\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDEFF])[\uFE00-\uFEFF]?/g, '');
}

我的使用场景是在数据网格中进行排序,其中表情符号可能会出现在字符串的开头,但用户希望按照实际单词对文本进行排序。

非常感谢您。有一件事我注意到它没有捕获所有的表情符号。我找到了另一个正则表达式字符串,但它做了一些奇怪的事情,比如删除前面的字符并添加字符。我似乎无法弄清楚它们之间的区别。这是在JSbin中您的代码与其他代码的比较链接:link - Steven Carlton
谢谢。这节省了我很多时间。别忘了在结尾加上.trim()以去除空格。 - rickchristie

3

sandre89的回答很好但并不完美。 我花了一些时间研究这个主题并找到了一个可行的解决方案。

var ranges = [
  '[\u00A0-\u269f]',
  '[\u26A0-\u329f]',
  // The following characters could not be minified correctly
  // if specifed with the ES6 syntax \u{1F400}
  '[-]'
  //'[\u{1F004}-\u{1F9C0}]'
];


$('#mybtn').on('click', function() {
  removeInvalidChars();
});

function removeInvalidChars() {
  var str = $('#myinput').val();
  str = str.replace(new RegExp(ranges.join('|'), 'ug'), '');
  $("#myinput").val(str);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="myinput" />
<input type="submit" id="mybtn" value="clear" />

这是我的 CodePen

但需要注意以下几点:

  1. U+1F000 开始的 Unicode 字符需要特殊注释,你可以使用 sandre89 的方式,或者选择 ES6 标准中的 \u{1F000} 注释方式,但后者可能无法与你的代码压缩器兼容。我成功地将表情图案直接粘贴到了 UTF-8 编码脚本中。

  2. 不要忘记正则表达式中的 u 标志,否则你的 JavaScript 引擎可能会报错。

由于文件编码、字符集或代码压缩器等问题,一些操作可能无法正常工作。在我的情况下,除非我将脚本从一个 .isml 文件(Demandware)中取出并粘贴到一个 .js 文件中,否则什么都不起作用。

你可以参考维基百科上的 Emoji 页面 一个 Unicode 字符占用多少字节?,还可以使用我使用过的 在线 Unicode 转换器


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