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

C++按空白分词时如何保留双引号包裹的含空格字符串

解决方案

原有分词逻辑直接按指定分隔符硬切割,未实现双引号字符串的识别规则,是导致带空格字符串被拆分错误的核心原因。采用逐字符遍历的简单状态机实现即可解决问题,逻辑可控且方便后续扩展语法规则。

核心逻辑只需要维护两个状态:

  • 普通分词状态:遇到空格、制表符就截断当前缓存内容作为独立token;遇到双引号时,先把已缓存的普通token存入结果,切换到字符串读取状态
  • 字符串读取状态:所有字符(包括空格、制表符)都直接存入当前缓存,直到遇到闭合的双引号,再把整个带引号的字符串作为完整token存入结果,切回普通分词状态

实现代码

#include <vector>
#include <string>

std::vector<std::string> tokenize(std::string str, char delim = ' ') {
    std::vector<std::string> out;
    std::string current_buf;
    bool in_quoted_string = false;

    for (char c : str) {
        if (in_quoted_string) {
            current_buf += c;
            // 碰到闭合双引号,结束字符串读取
            if (c == '"') {
                in_quoted_string = false;
                out.push_back(current_buf);
                current_buf.clear();
            }
        } else {
            if (c == '"') {
                // 碰到字符串起始标记,先把之前缓存的普通token存下
                if (!current_buf.empty()) {
                    out.push_back(current_buf);
                    current_buf.clear();
                }
                in_quoted_string = true;
                current_buf += c;
            } else if (c == delim || c == '\t') {
                // 碰到分隔符/制表符,截断普通token
                if (!current_buf.empty()) {
                    out.push_back(current_buf);
                    current_buf.clear();
                }
            } else {
                current_buf += c;
            }
        }
    }
    // 处理遍历结束后剩余的缓存内容
    if (!current_buf.empty()) {
        out.push_back(current_buf);
    }

    return out;
}

效果说明

  • 输入print "hello are you there?"时,分词结果为["print", "\"hello are you there?\""],带空格的字符串会被识别为单个独立token,不会触发关键字识别错误
  • 非引号包裹的普通标识符、关键字仍然按空白字符正常拆分,和原有逻辑的预期行为一致
  • 后续如果需要支持转义字符(比如字符串内部通过\"表示双引号本身),只需要在字符串状态下增加一个转义标记位即可判断,扩展成本极低

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 17:01:40