You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何拆分包含表情符号与拉丁字母的字符串,将每个表情作为独立单词

C++ 混合普通单词与表情字符串拆分方案

需求定义

  • 输入:UTF-8编码的字符串,混合普通单词、空格、Unicode表情
  • 输出:std::vector<std::string>,规则如下:
    • 空格分隔的普通单词作为单个元素
    • 每个表情单独作为一个元素,连续多个表情各自独立拆分
  • 示例效果:

输入:"The Quick 🙂 Brown Fox Jumps 🙂🙂🙂 Over Lazy Dog"
输出:["The", "Quick", "🙂", "Brown", "Fox", "Jumps", "🙂", "🙂", "🙂", "Over", "Lazy", "Dog"]

轻量无依赖实现方案(C++11及以上支持)

无需引入第三方库,直接通过UTF-8码点识别实现,代码如下:

#include <vector>
#include <string>
#include <utility>
#include <cstdint>

// 判断Unicode码点是否属于常见表情范围
bool is_emoji(uint32_t cp) {
    return (cp >= 0x1F600 && cp <= 0x1F64F) // 面部表情
        || (cp >= 0x1F300 && cp <= 0x1F5FF) // 通用象形符号
        || (cp >= 0x1F680 && cp <= 0x1F6FF) // 交通与标识符号
        || (cp >= 0x2600 && cp <= 0x26FF)   // 杂项符号
        || (cp >= 0x2700 && cp <= 0x27BF)   // 装饰符号
        || (cp >= 0x1F900 && cp <= 0x1F9FF); // 补充表情符号
}

// 读取UTF-8字符串中当前位置的Unicode码点,返回码点值和占用字节数
std::pair<uint32_t, int> parse_next_codepoint(const char* str_ptr) {
    uint8_t first_byte = static_cast<uint8_t>(*str_ptr);
    if (first_byte < 0x80) {
        return {static_cast<uint32_t>(first_byte), 1};
    } else if (first_byte < 0xE0) {
        uint32_t cp = ((first_byte & 0x1F) << 6) | (static_cast<uint8_t>(*(str_ptr + 1)) & 0x3F);
        return {cp, 2};
    } else if (first_byte < 0xF0) {
        uint32_t cp = ((first_byte & 0x0F) << 12) 
                    | ((static_cast<uint8_t>(*(str_ptr + 1)) & 0x3F) << 6) 
                    | (static_cast<uint8_t>(*(str_ptr + 2)) & 0x3F);
        return {cp, 3};
    } else {
        uint32_t cp = ((first_byte & 0x07) << 18) 
                    | ((static_cast<uint8_t>(*(str_ptr + 1)) & 0x3F) << 12) 
                    | ((static_cast<uint8_t>(*(str_ptr + 2)) & 0x3F) << 6) 
                    | (static_cast<uint8_t>(*(str_ptr + 3)) & 0x3F);
        return {cp, 4};
    }
}

std::vector<std::string> split_string_with_emoji(const std::string& input) {
    std::vector<std::string> result;
    std::string current_plain_word;
    int pos = 0;
    const int str_len = input.size();

    while (pos < str_len) {
        auto [codepoint, byte_count] = parse_next_codepoint(input.c_str() + pos);
        if (is_emoji(codepoint)) {
            // 先存入之前积攒的普通单词
            if (!current_plain_word.empty()) {
                result.push_back(current_plain_word);
                current_plain_word.clear();
            }
            // 单独存入当前表情
            result.push_back(input.substr(pos, byte_count));
        } else if (codepoint == ' ') {
            // 空格作为普通单词分隔符
            if (!current_plain_word.empty()) {
                result.push_back(current_plain_word);
                current_plain_word.clear();
            }
        } else {
            // 普通字符追加到当前单词
            current_plain_word.append(input, pos, byte_count);
        }
        pos += byte_count;
    }

    // 存入最后剩余的普通单词
    if (!current_plain_word.empty()) {
        result.push_back(current_plain_word);
    }

    return result;
}

编译与使用说明

直接使用支持C++11及以上标准的编译器编译即可,编译命令示例:
g++ your_file.cpp -o split_demo -std=c++11
如果需要支持带肤色、联合类的多码点表情,可以扩展is_emoji的判断范围,或者引入ICU Unicode库做更专业的边界识别。


内容的提问来源于stack exchange,提问作者green123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 04:15:03