058-差不多是Java中最好用的Emoji库了

2,193 阅读4分钟

这是坚持技术写作计划(含翻译)的第58篇,定个小目标999,每周最少2篇。


本文主要讲解java中最好用的emoji库 vdurmont/emoji-java ,以及我提交的PR #175 用于解决 emoji-java 表情更新不及时,及本地化方面的改进


什么是emoji

emoji是表情符号/颜文字/绘文字,与表情包堪称现代人社交离不开的两个功能,区别是,表情包一般是用于非正式场合甚至带点恶搞的意思,而emoji稍微正式些(比如拍领导马屁专用,赞:👍,拍手:👏),
而发给领导,则会有失业风险

在一些国际网络交流中,emoji能够比较方便的增加双方交流,比如不存在的幽灵网站,某推,某书,某ins,emoji非常流行

欢迎大家来吐槽下,你是啥时候更深入的了解到emoji的(日常聊天除外)?或者说,有多少人是因为mysql阉割版utf8而被emoji坑过?

一般用户昵称,用户评论属于重灾区。。。

解决方案无非两个,
1,将emoji替换成空字符串,以java为例str.replaceAll("^\\p{L}\\p{M}\\p{N}\\p{P}\\p{Z}\\p{Cf}\\p{Cs}\\p{Sc}\\s]", "")
2,修改mysql列类型为utf8mb4或者换数据库pgsql等

emoji-java简介及使用


如果有人用过hutool工具包,那可能有用过如下语法 参考 Emoji工具-EmojiUtil

String alias = EmojiUtil.toAlias("😄");//:smile:
String emoji = EmojiUtil.toUnicode(":smile:");//😄
String alias = EmojiUtil.toHtml("😄");//👦

此处,hutool就是基于 vdurmont/emoji-java 库来做的

简单来说,emoji-java 库是一个java的emoji工具库,主要用于判断文本是否含有emoji表情,将emoji替换为文本描述(比如将 😄 替换成 :smile: ),也可以将描述,逆向成emoji表情,比如 :smile: 😄

移除emoji表情

String str = "An 😀awesome 😃string with a few 😉emojis!";
Collection<Emoji> collection = new ArrayList<Emoji>();
collection.add(EmojiManager.getForAlias("wink")); // This is 😉

System.out.println(EmojiParser.removeAllEmojis(str));
System.out.println(EmojiParser.removeAllEmojisExcept(str, collection));
System.out.println(EmojiParser.removeEmojis(str, collection));

// Prints:
// "An awesome string with a few emojis!"
// "An awesome string with a few 😉emojis!"
// "An 😀awesome 😃string with a few emojis!"


基本使用,参见他的README.md,功能很简单,也很实用
目前支持的所有emoji,参见他的EMOJIS.md ,里面没有列出来的,则暂未支持

是的,他采取的是白名单的做法,列出的是emoji,没有列出的,则不是emoji

下面例子可能会更方便理解

// https://unicode.org/emoji/charts/full-emoji-list.html#1f636_200d_1f32b_fe0f
EmojiManager.isEmoji("😶‍🌫️") //false

具体案例表情参见 unicode.org/emoji/chart…
与 emoji 13.1 规范相比, emoji-java 5.1.1 一共缺失 244个表情,详见 我提的 issues

对于一个公共库来说,算是缺失比较多的了

对emoji-java打补丁

针对上一个问题,我抽空提交了一个feat(module): add emoji-json-generator module #175
以后可以基于unicode.org/emoji/chart… 自己生成emoji.json,能够保证实时性

mvn exec:java -Dexec.mainClass="com.vdurmont.emoji.JsonGenerator" [-Dexec.args="proxy=1270.0.1 port=1080 \
    path=path\to\already\download\emoji.html save_url=/path/to/emoji.json \
    url=https://unicode.org/emoji/charts/full-emoji-list.html \
    emoji_path=/path/to/already/emoji.json \
    emoji_i18n_path=/path/to/i18n_description/emoji_i18n.json
    "]

简单说明下

  • []:包裹的,都是选填的,不写没关系
  • proxy 和port: 是防止访问unicode.org/emoji/chart… 失败,可以自己设置代理服务器(比如国外或者香港的)
  • path:如果不想每次实时访问 unicode.org/emoji/chart… 可以预先下载到本地,然后读本地的,这是路径地址
  • save_url: 这是重新生成的 emoji.json 地址
  • url: 防止 unicode.org/emoji/chart… 改地址
  • emoji_path: 是为了兼容emoji-java官方库 github.com/anjia0532/e… ,防止从 unicode.org/emoji/chart… 生成的跟之前的不一样,导致库里对应不上,如果设置了emoji_path,并且能够匹配上的,以emoji_path的为准
  • emoji_i18n_path:如果是想将 👀 对应的解释从 eyes  换成中文 两只眼睛 ,那么就设置需要翻译的json路径,格式参考 github.com/anjia0532/e…


自己生成的emoji.json 如何使用呢
第一种方案:
自己fork并生成emoji.json覆盖原来的emoji.json并打包发到私服上,这样原代码不用动,兼容性最好,改动最小

第二种方案:
自己fork并修改 EmojiManager,因为他本身写死了,不支持外部传入emoji.json的路径或者文件流

第三种方案:
在自己项目里参考 EmojiManager 自行实现类似的静态工具类 主要是用 EmojiLoader加载emoji.json转成 List,并转换成EmojiTrie

招聘小广告


山东济南的小伙伴欢迎投简历啊 加入我们 , 一起搞事情。
长期招聘,Java程序员,大数据工程师,运维工程师,前端工程师。

参考资料