如何用多分隔符解析SQL语句的SELECT与ORDERBY部分?
解决C++多分隔符解析SQL的简便方法
核心思路
不用逐个处理分隔符,直接借助C++标准库的stringstream结合自定义字符分类规则,一次性识别空格、冒号、逗号作为分隔符,高效提取SELECT和ORDERBY部分的目标字段。
具体实现步骤
- 截取目标子串:先从完整SQL中单独提取
SELECT ... FROM和ORDERBY ...;这两段核心内容,避免无关语句干扰解析。 - 自定义分隔符规则:通过重载
ctypefacet,将空格、冒号、逗号标记为分隔符,让stringstream自动按这些字符拆分字符串。 - 提取有效字段:遍历拆分后的token,当遇到值为
1的标记时,将其前一个token(字段名)加入结果列表。
完整代码示例
#include <iostream> #include <string> #include <sstream> #include <vector> #include <locale> // 自定义分隔符的字符分类规则 struct MultiDelimiter : std::ctype<char> { MultiDelimiter() : std::ctype<char>(get_table()) {} static const mask* get_table() { static std::vector<mask> rc(table_size, mask()); rc[' '] = std::ctype_base::space; rc[':'] = std::ctype_base::space; rc[','] = std::ctype_base::space; return &rc[0]; } }; // 解析字段的通用函数 std::vector<std::string> parse_fields(const std::string& input) { std::vector<std::string> fields; std::stringstream ss(input); // 注入自定义分隔符规则 ss.imbue(std::locale(ss.getloc(), new MultiDelimiter)); std::string token; std::string prev_token; while (ss >> token) { if (token == "1" && !prev_token.empty()) { fields.push_back(prev_token); prev_token.clear(); } else { prev_token = token; } } return fields; } int main() { std::string sql = "SELECT LNAME:1,FNAME:1,SALARY:1 FROM EMPLOYEE WHERE SALARY >= 30000 ORDERBY SALARY:1;"; // 提取SELECT部分 size_t select_start = sql.find("SELECT") + 6; size_t select_end = sql.find("FROM"); std::string select_part = sql.substr(select_start, select_end - select_start); auto select_fields = parse_fields(select_part); std::cout << "解析SELECT字段:" << std::endl; for (const auto& f : select_fields) { std::cout << "- " << f << std::endl; } // 提取ORDERBY部分 size_t orderby_start = sql.find("ORDERBY") + 7; size_t orderby_end = sql.find(";"); std::string orderby_part = sql.substr(orderby_start, orderby_end - orderby_start); auto orderby_fields = parse_fields(orderby_part); std::cout << "\n解析ORDERBY字段:" << std::endl; for (const auto& f : orderby_fields) { std::cout << "- " << f << std::endl; } return 0; }
代码说明
- 自定义
MultiDelimiter:将空格、冒号、逗号统一标记为空格类字符,stringstream读取时会自动跳过这些分隔符,直接返回连续的字段名或标记值。 - 字段提取逻辑:通过记录前一个token,匹配
字段名:1的格式,精准提取需要的字段名称。 - 子串截取:先分离出需要解析的目标段落,避免WHERE等其他语句的内容干扰解析流程。
运行结果
解析SELECT字段: - LNAME - FNAME - SALARY 解析ORDERBY字段: - SALARY
内容的提问来源于stack exchange,提问作者anirudh raghavan
相关产品推荐
相关产品推荐

