JS Emoji 过滤

想用的直接看最后一行就好

基础知识

不得不承认阮蜀黍的文笔通俗易懂

Emoji Unicode Tables

  1. Emoticons ( 1F601 - 1F64F )
  2. Dingbats ( 2702 - 27B0 )
  3. Transport and map symbols ( 1F680 - 1F6C0 )
  4. Enclosed characters ( 24C2 - 1F251 )
  5. Uncategorized
  6. Additional
    1. Additional emoticons ( 1F600 - 1F636 )
    2. Additional transport and map symbols ( 1F681 - 1F6C5 )
    3. Other additional symbols ( 1F30D - 1F567 )

转换?

只怪 JavaScript 你诞生的太早

JavaScript 只识别 UCS-2,对于 UTF-16 的 4 个编码来说,只能识别为 2 个单独的字符

友好的 ES6

ES6 对 Unicode 做了大幅增强支持

1
'\u{1f604}' === '\ud83d\ude04' // true

笨笨的我

然而我并不知道 ‘:smile:’.replace(/\u{1f604}/g, “”) 这个的正则要怎么写,So,只能把带有辅助平面字符的 unicode 转换为 2 个单独的字符

1
2
3
4
var unicode2UTF16 = function (unicode) {
const h = Math.floor((unicode - 0x10000) / 0x400) + 0xD800;
const l = (unicode - 0x10000) % 0x400 + 0xDC00;
return '\\u' + h.toString(16) + '\\u' + l.toString(16);}

map

细细看下来,Emoji Unicode Tables 给的范围不按顺序出牌。Uncategorized 直接乱了爸妈都不认识,瞎眼整理:

\ud83d[\udc00-\udec5]

  • 0x1F601(\ud83d\ude01) - 0x1F64F(\ud83d\ude4f)
  • 0x1F600(\ud83d\ude00) - 0x1F636(\ud83d\ude36)
  • 0x1F680(\ud83d\ude80) - 0x1F6C0(\ud83d\udec0)
  • 0x1F681(\ud83d\ude81) - 0x1F6C5(\ud83d\udec5)
  • 0x1F400(\ud83d\udc00) - 0x1F567(\ud83d\udd67)

\ud83c[\udd70-\udf4e]

  • 0x1F30D(\ud83c\udf0d) - 0x1F3E4(\ud83c\udfe4)
  • 0x1F170(\ud83c\udd70) - 0x1F251(\ud83c\ude51)

XXXXYYYYOOOO

结果

如果要弄太花费精力,还是网上搜了下,选了个大的(最后一个)。。。

  • \ud83d[\udc00-\udec5]|\ud83c[\udd70-\udf4e]
  • \ud83c[\udf00-\udfff]|\ud83d[\udc00-\ude4f]
  • \ud83c[\udc00-\udfff]|\ud83d[\udc00-\udfff]|[\u2000-\u2fff]
1
return str.replace(/\ud83c[\udc00-\udfff]|\ud83d[\udc00-\udfff]|[\u2000-\u2fff]/g, "")