随着表情的大量使用,在微信开发中,开发人员不得不考虑对表情的处理。
微信上的表情大致可以分为三类。
第一类是收藏的表情,像下面这样的
这种表情从微信端发到服务器是这样的
这类表情无法处理。
另一类是微信自带的表情
这类表情发过来是符号,比如第一个微笑表情发过来是这个符号/::)
最后一类是emoji表情,emoji表情在java都是不可见编码,发过看到的是一个像空格一样的。
第一类表情无法处理,只能丢弃掉,而且微信发第一类表情的时候是无法同时发文字和表情的,只能发一个表情,所以对业务影响也不大。
第二类表情和第三类表情可以归为同一类,只不过第三类我们看不到,一旦对其进行编码,就能看到了。
处理表情的思路就是做一个编码表。
对于不可见的emoji可以用Unicode区分
emoji的unicode对照表参考
第二类表情已经有人整理好了
参考
微信默认表情代码和图片包
缺少几个表情
到目前,微信自带的表情(2017年3月21日)有99个,微信默认表情代码和图片包中还有9个表情没有。
不过在微信web版里也没有那9个表情,我也没有找到那几个表情的资源文件,我通过截图把剩下的9个自带表情加了进去,还望知道微信官方表情包下载地址资源文件的告知一下。
emoji表情微信默认表情代码和图片包已经给了部分emoji表情以及对应关系。完全是体力活,剩下的emoji表情就不一一添加了。
一些emoji表情的截图,这种像口的不可见字符可以通过Unicode查看不同。
缺失的表情
#缺失的那9张表情
[囧]=<img class="wechat-emoji" src="/jrbac/assets/image/emoji/wechat/jiong.png" alt="囧">
[嘿哈]=<img class="wechat-emoji" src="/jrbac/assets/image/emoji/wechat/heiha.png" alt="嘿哈">
[捂脸]=<img class="wechat-emoji" src="/jrbac/assets/image/emoji/wechat/wulian.png" alt="捂脸">
[奸笑]=<img class="wechat-emoji" src="/jrbac/assets/image/emoji/wechat/jianxiao.png" alt="奸笑">
[机智]=<img class="wechat-emoji" src="/jrbac/assets/image/emoji/wechat/jizhi.png" alt="机制">
[皱眉]=<img class="wechat-emoji" src="/jrbac/assets/image/emoji/wechat/zhoumei.png" alt="皱眉">
[耶]=<img class="wechat-emoji" src="/jrbac/assets/image/emoji/wechat/ye.png" alt="耶">
[红包]=<img class="wechat-emoji" src="/jrbac/assets/image/emoji/wechat/hongbao.png" alt="红包">
[鸡]=<img class="wechat-emoji" src="/jrbac/assets/image/emoji/wechat/ji.png" alt="鸡">
emoji
如何判断一句话中哪些是emoji哪些是文字呢?这里提供一个工具类,工具类中是将emoji转换为unicode编码,可以将其替换为图片,或者用空格过滤掉。
package com.jrbac.util;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EmojiUtil {
/**
* 显示不可见字符的Unicode
*
* @param input
* @return
*/
public static String escapeUnicode(String input) {
StringBuilder sb = new StringBuilder(input.length());
@SuppressWarnings("resource")
Formatter format = new Formatter(sb);
for (char c : input.toCharArray()) {
if (c < 128) {
sb.append(c);
} else {
format.format("\\u%04x", (int) c);
}
}
return sb.toString();
}
/**
* 将emoji替换为unicode
*
* @param source
* @return
*/
public static String filterEmoji(String source) {
if (source != null) {
Pattern emoji = Pattern.compile("[\ue000-\uefff]", Pattern.CASE_INSENSITIVE);
Matcher emojiMatcher = emoji.matcher(source);
Map<String, String> tmpMap = new HashMap<>();
while (emojiMatcher.find()) {
// System.out.println(escapeUnicode(emojiMatcher.group()));
// System.out.println(emojiMatcher.start());
String key = emojiMatcher.group();
String value = escapeUnicode(emojiMatcher.group());
//System.out.println("key:" + key);
//System.out.println("value:" + value);
tmpMap.put(key, value);
// source =
// emojiMatcher.replaceAll(escapeUnicode(emojiMatcher.group()));
}
if (!tmpMap.isEmpty()) {
for (Map.Entry<String, String> entry : tmpMap.entrySet()) {
String key = entry.getKey().toString();
String value = entry.getValue().toString();
source = source.replace(key, value);
}
}
}
return source;
}
}
测试
package com.jrbac.util;
import org.junit.Test;
public class EmojiTest {
@Test
public void testEmoji() {
String source = "基本表情/::)emoji苹果emoji面包";
String unicode = EmojiUtil.escapeUnicode(source);
System.out.println("原始字符串:"+source);
System.out.println("unicode编码:"+unicode);
String replace = EmojiUtil.filterEmoji(source);
System.out.println("替换后的字符串:"+replace);
}
}
效果
参考文献