自己实现的使用c++解析文本中的emoji表情

https://blog.csdn.net/muwuxin/article/details/88896188

程序要求实现文本内容的emoji表情显示,通过多方资料查询,以及官网emoji表情和Unicode的对照表,自己实现了一套解析emoji的方法,目前基本满足程序的需求。

具体实现逻辑是将string转成wstring,然后遍历每个字符,判断是否是emoji表情,将文本拆分成若干块,然后界面再去处理,其中最主要的就是emoji表情的判断,通过实际发送emoji表情,总结出以下几种表情类型:

1、基本的表情,这类表情的对应utf-8编码又分为两种,例如 哈哈 这个表情的编码是\ud83d\ude04 占了两个字节长度,心 这个表情的编码为\u2764 只占了一个字节长度,这是因为emoji在Unicode中的编码范围不同,有一定的规律可循。

2、组合表情,这类表情是通过连接符\u200d连接,可能是多个基本表情组成的一个,也可能是一个表情加上颜色等样式,这样就会出现接收到很长一个字符串,最后解析出来只有一个表情符号的情况。

3、特殊的数字表情,常见的就是0-9带一个框的,这种的编码又有所不同,例如 1 是1\ufe0f\u20e3,2 是 2\ufe0f\u20e3,规律相同,都是数字后跟\ufe0f\u20e3。

4、一些旗帜表情,多数以\ud83c开始,但是\ud83c在组合表情中又用来连接表情的样式的,由于我的程序需求只需要处理100多个基本表情,没有涉及到旗子这块,所以没有处理,直接用缺省表情表示了

以上是我自己通过手机发送表情总结出来的,如果有哪些不对的地方,请大佬指正。

下边是部分具体实现的代码。

bool isEmoji(int value, int &count)
{
    //0x200d -- 连接符  0xd83c----好像是颜色分割符 或者是旗帜?  0xfe0f ---好像是表情结束符  0xfe0f0x20e3--特殊符号的表情
    if ((value >= 0xd800 && value <= 0xdbff))
    {
        count = 2;
        return true;
    }
    else if ((0x2100 <= value && value <= 0x27ff && value != 0x263b)
        || (0x2b05 <= value && value <= 0x2b07)
        || (0x2934 <= value && value <= 0x2935)
        || (0x3297 <= value && value <= 0x3299)
        || value == 0xa9 || value == 0xae || value == 0x303d || value == 0x3030
        || value == 0x2b55 || value == 0x2b1c || value == 0x2b1b || value == 0x2b50
        || value == 0x231a)
    {
        count = 1;
        return true;
    }
    return false;
}
用来判断字符是否是emoji表情,输入一个字节还是两个字节的表情。

string dealString(const string& content, const string &emoji)
{
    wstring str = HelpFun::str2wstr(content);
    int pos = 0;
    string strAim = "";
    bool hasEmoji = false;
    string curEmoji = "";
    int iTotalLength = str.length();
    for (int j = 0; j < iTotalLength; j++)
    {
        if (!hasEmoji)
        {
            int eCount = 0;
            if (isEmoji(str.at(j), eCount))
            {
                hasEmoji = true;
                if (eCount == 1)
                {
                    curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str());
                }
                else if (eCount == 2)
                {
                    curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str());
                    if (j < iTotalLength - 1)
                    {
                        pos++;
                        j++;
                        curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str());
                    }
                }
            }
            else if (j < iTotalLength - 1 &&(str.at(j) == 0xfe0f && str.at(j + 1) == 0x20e3))
            {
                j++;
                pos++;
            }
            else
            {
                strAim.append(HelpFun::wstr2str(str.substr(pos, 1)));
            }
        }
        else
        {
            if (str.at(j) == 0xfe0f)
            {
                strAim.append(emoji);
                curEmoji = "";
                hasEmoji = false;
            }
            else if (str.at(j) == 0x200d)
            {
                hasEmoji = false;
            }
            else if (j < iTotalLength - 1 && str.at(j) == 0xd83c)
            {
                if (str.at(j+1) >= 0xdf00)    //颜色
                {
                    curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str());
                    j++;
                    pos++;
                    curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str());
                }
                else
                {//旗子
                    curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str());
                    j++;
                    pos++;
                    curEmoji.append(StringUtils::format("%04x", str.at(j)).c_str());
                    strAim.append(emoji);
                    curEmoji = "";
                    hasEmoji = false;
                }
            }
            else
            {
                strAim.append(emoji);
                curEmoji = "";
                hasEmoji = false;
                j--;
                pos--;
            }
        }
        pos++;
    }
    if (hasEmoji)
    {
        strAim.append(emoji);
    }
    return strAim;
}
解析文本,将emoji表情替换成对应的编码输出出来。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/muwuxin/article/details/88896188

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值