在C++中(借助Boost?)分词处理大括号初始化列表风格字符串
解决方案:解析C++风格大括号初始化列表为字符串向量
这种带嵌套大括号和引号的结构化字符串,用正则确实搞不定嵌套逻辑,得手动写个状态机来处理才靠谱。我写了个C++函数,正好能满足你的需求——支持保留嵌套列表、带引号的token,还能正确忽略引号和嵌套括号里的逗号分隔符:
#include <vector> #include <string> #include <cctype> std::vector<std::string> parse_brace_init_list(const std::string& input) { std::vector<std::string> result; std::string current_token; bool in_quote = false; int brace_depth = 0; for (size_t i = 0; i < input.size(); ++i) { char c = input[i]; // 处理转义引号(\"),直接保留转义序列 if (c == '\\' && i + 1 < input.size() && input[i+1] == '"') { current_token += c; current_token += input[i+1]; ++i; // 跳过已处理的引号 continue; } // 切换引号状态 if (c == '"' && !in_quote) { in_quote = true; current_token += c; } else if (c == '"' && in_quote) { in_quote = false; current_token += c; } // 处理大括号嵌套深度 else if (c == '{' && !in_quote) { ++brace_depth; current_token += c; } else if (c == '}' && !in_quote) { if (brace_depth > 0) { --brace_depth; current_token += c; } } // 只有不在引号、且当前大括号深度为0时,逗号才是分隔符 else if (c == ',' && !in_quote && brace_depth == 0) { // 清理token前后的空白字符 size_t start = current_token.find_first_not_of(" \t\n\r"); size_t end = current_token.find_last_not_of(" \t\n\r"); if (start != std::string::npos && end != std::string::npos) { result.push_back(current_token.substr(start, end - start + 1)); } current_token.clear(); } // 其他字符直接加入当前token else { current_token += c; } } // 处理最后一个未被逗号分隔的token if (!current_token.empty()) { size_t start = current_token.find_first_not_of(" \t\n\r"); size_t end = current_token.find_last_not_of(" \t\n\r"); if (start != std::string::npos && end != std::string::npos) { result.push_back(current_token.substr(start, end - start + 1)); } } return result; }
关键逻辑说明
- 状态跟踪:用
in_quote标记是否处于引号内,brace_depth记录当前嵌套的大括号深度,精准区分哪些逗号是真正的元素分隔符。 - 转义处理:遇到
\"时直接保留转义序列,不会误判为引号的开闭标志。 - 空白清理:自动去除每个token前后的空白字符,比如输入里的
one, two会被处理成"one"和"two",更贴合实际使用场景。
测试你的示例输入
输入字符串:
"{one, {2, \"three four\"}}, \"five, six\", {\"seven, eight\"}}"
函数返回的vector包含4个元素:
"one""{2, \"three four\"}""\"five, six\"""{\"seven, eight\"}"
完全符合你的需求,你可以直接拿去用,或者根据自己的场景调整细节(比如要不要保留前后空白、是否需要处理其他转义字符等)。
内容的提问来源于stack exchange,提问作者DiB
相关产品推荐
相关产品推荐

