参考:https://blog.csdn.net/muwuxin/article/details/88896188
https://bbs.csdn.net/topics/391989473
思路:获取输入的Unicode编码,根据编码判断是否是Emoji表情
Emoji表情对应的Unicode编码可以从https://www.wiki-wiki.top/wiki/Emoji查到:
例如这个红框标出的Emoji表情对应的Unicode编码为0xA9
以下为转载:
程序要求实现文本内容的emoji表情显示,通过多方资料查询,以及官网emoji表情和Unicode的对照表,自己实现了一套解析emoji的方法,目前基本满足程序的需求。
具体实现逻辑是将string转成wstring,然后遍历每个字符,判断是否是emoji表情,将文本拆分成若干块,然后界面再去处理,其中最主要的就是emoji表情的判断,通过实际发送emoji表情,总结出以下几种表情类型:
1、基本的表情,这类表情的对应utf-8编码又分为两种,例如 哈哈 这个表情的编码是ud83dude04 占了两个字节长度,心 这个表情的编码为u2764 只占了一个字节长度,这是因为emoji在Unicode中的编码范围不同,有一定的规律可循。
2、组合表情,这类表情是通过连接符u200d连接,可能是多个基本表情组成的一个,也可能是一个表情加上颜色等样式,这样就会出现接收到很长一个字符串,最后解析出来只有一个表情符号的情况。
3、特殊的数字表情,常见的就是0-9带一个框的,这种的编码又有所不同,例如 1 是1ufe0fu20e3,2 是 2ufe0fu20e3,规律相同,都是数字后跟ufe0fu20e3。
4、一些旗帜表情,多数以ud83c开始,但是ud83c在组合表情中又用来连接表情的样式的,由于我的程序需求只需要处理100多个基本表情,没有涉及到旗子这块,所以没有处理,直接用缺省表情表示了
以上是我自己通过手机发送表情总结出来的,如果有哪些不对的地方,请大佬指正。
1 bool isEmoji(int value, int &count) 2 { 3 //0x200d -- 连接符 0xd83c----好像是颜色分割符 或者是旗帜? 0xfe0f ---好像是表情结束符 0xfe0f0x20e3--特殊符号的表情 4 if ((value >= 0xd800 && value <= 0xdbff)) 5 { 6 count = 2; 7 return true; 8 } 9 else if ((0x2100 <= value && value <= 0x27ff && value != 0x263b) 10 || (0x2b05 <= value && value <= 0x2b07) 11 || (0x2934 <= value && value <= 0x2935) 12 || (0x3297 <= value && value <= 0x3299) 13 || value == 0xa9 || value == 0xae || value == 0x303d || value == 0x3030 14 || value == 0x2b55 || value == 0x2b1c || value == 0x2b1b || value == 0x2b50 15 || value == 0x231a) 16 { 17 count = 1; 18 return true; 19 } 20 return false; 21 }
用来判断字符是否是emoji表情,输入一个字节还是两个字节的表情。
1 string dealString(const string& content, const string &emoji) 2 { 3 wstring str = HelpFun::str2wstr(content); 4 int pos = 0; 5 string strAim = ""; 6 bool hasEmoji = false; 7 string curEmoji = ""; 8 int iTotalLength = str.length(); 9 for (int j = 0; j < iTotalLength; j++) 10 { 11 if (!hasEmoji) 12 { 13 int eCount = 0; 14 if (isEmoji(str.at(j), eCount)) 15 { 16 hasEmoji = true; 17 if (eCount == 1) 18 { 19 curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str()); 20 } 21 else if (eCount == 2) 22 { 23 curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str()); 24 if (j < iTotalLength - 1) 25 { 26 pos++; 27 j++; 28 curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str()); 29 } 30 } 31 } 32 else if (j < iTotalLength - 1 &&(str.at(j) == 0xfe0f && str.at(j + 1) == 0x20e3)) 33 { 34 j++; 35 pos++; 36 } 37 else 38 { 39 strAim.append(HelpFun::wstr2str(str.substr(pos, 1))); 40 } 41 } 42 else 43 { 44 if (str.at(j) == 0xfe0f) 45 { 46 strAim.append(emoji); 47 curEmoji = ""; 48 hasEmoji = false; 49 } 50 else if (str.at(j) == 0x200d) 51 { 52 hasEmoji = false; 53 } 54 else if (j < iTotalLength - 1 && str.at(j) == 0xd83c) 55 { 56 if (str.at(j+1) >= 0xdf00) //颜色 57 { 58 curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str()); 59 j++; 60 pos++; 61 curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str()); 62 } 63 else 64 {//旗子 65 curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str()); 66 j++; 67 pos++; 68 curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str()); 69 strAim.append(emoji); 70 curEmoji = ""; 71 hasEmoji = false; 72 } 73 } 74 else 75 { 76 strAim.append(emoji); 77 curEmoji = ""; 78 hasEmoji = false; 79 j--; 80 pos--; 81 } 82 } 83 pos++; 84 } 85 if (hasEmoji) 86 { 87 strAim.append(emoji); 88 } 89 return strAim; 90 }
解析文本,将emoji表情替换成对应的编码输出出来。