C++ 中,字符串分词(tokenize)可以通过多种方式实现,常见方法包括使用 std::stringstream(适合简单分隔符,语法清晰易用)、strtok(C 风格,会修改原字符串,适用于兼容老代码)、std::regex(支持复杂分隔符,功能强大但性能略低)以及手动查找分隔符切割(灵活可控,不依赖额外库)。根据需求选择合适方法,可高效实现字符串的分割处理。

1、使用 strtok 函数(标准做法)

使用 std::stringstream 对字符串进行分词(Tokenize)的 推荐 C++ 实现方式,适用于使用简单分隔符(如逗号、空格等)的场景。

#include <iostream>
#include <sstream>
#include <vector>
#include <string>

int main() {
    std::string str = "apple,banana,pear";
    char delimiter = ',';
    std::stringstream ss(str);
    std::string token;

    std::vector<std::string> tokens;

    // 使用 getline 按分隔符提取子串
    while (std::getline(ss, token, delimiter)) {
        tokens.push_back(token);
    }

    // 输出分词结果
    for (const auto& t : tokens) {
        std::cout << "Token: " << t << std::endl;
    }

    return 0;
}

2、使用 C 风格的 strtok(适用于 C 字符串)

使用 strtok 函数对字符串进行分词(Tokenize),strtok 会修改原始字符串,将分隔符替换为 \0。原始字符串必须是可修改的字符数组(char[]),不能直接使用 std::string。多线程环境中不推荐使用 strtok,可以改用线程安全版本 strtok_r(在 POSIX 系统上可用)。

#include <iostream>
#include <cstring>  // 包含 strtok 和 strlen

int main() {
    char str[] = "apple,banana,pear";  // 注意是 char 数组,不能用 string
    const char* delim = ",";

    char* token = std::strtok(str, delim);  // 第一次传入原始字符串
    while (token != nullptr) {
        std::cout << "Token: " << token << std::endl;
        token = std::strtok(nullptr, delim);  // 后续传入 NULL,继续上一次的位置
    }

    return 0;
}

3、使用 std::regex(支持复杂分隔符)

支持多个字符或复杂正则作为分隔符(例如多个逗号、空格、管道符等),不会修改原始字符串,更灵活,适合复杂文本处理场景。

#include <iostream>
#include <regex>
#include <string>
#include <iterator>

int main() {
    std::string text = "apple, orange;banana  mango,,grape";
    // 使用正则表达式匹配一个或多个逗号、分号或空格作为分隔符
    std::regex re("[,;\\s]+");

    std::sregex_token_iterator iter(text.begin(), text.end(), re, -1);
    std::sregex_token_iterator end;

    for (; iter != end; ++iter) {
        if (!iter->str().empty()) {  // 跳过空字符串
            std::cout << "Token: " << *iter << std::endl;
        }
    }

    return 0;
}

4、手动查找分隔符并切割

手动查找分隔符并切割字符串 是一种无需依赖外部库的方法,适用于需要更高灵活性或对性能有要求的场景。

#include <iostream>
#include <vector>
#include <string>

// 自定义分词函数
std::vector<std::string> split(const std::string& str, char delimiter) {
    std::vector<std::string> result;
    size_t start = 0;
    size_t pos;

    while ((pos = str.find(delimiter, start)) != std::string::npos) {
        result.push_back(str.substr(start, pos - start));  // 提取子串
        start = pos + 1;  // 移动起始位置
    }

    result.push_back(str.substr(start));  // 添加最后一段
    return result;
}

int main() {
    std::string text = "apple,banana,pear";
    std::vector<std::string> tokens = split(text, ',');

    for (const auto& token : tokens) {
        std::cout << "Token: " << token << std::endl;
    }

    return 0;
}