解析含特殊字符的ODBC连接字符串:需求有效性及代码优化
ODBC连接字符串PWD键值解析规则与代码修正
1. 关于PWD={a{b}};c};的合法性与解析结果
根据ODBC的SQLDriverConnect规范:
- 当关键字的值包含分号、大括号等特殊字符时,必须用大括号
{}包裹整个值 - 在大括号包裹的内容中,两个连续的大括号
}}表示一个实际的},而单个的}会被当作包裹的结束标记
所以你给出的PWD={a{b}};c};格式不符合规范:解析器从第一个{开始读取,遇到a{b后的单个}时会判定包裹结束,最终解析出的PWD值是a{b},剩下的};c};会被当作无效的后续字段处理,无法得到你预期的a{b}};c。
如果要让解析结果为a{b}};c,正确的连接字符串格式应为PWD={a{b}}};c};——这里的}}}表示:前两个}}是转义的单个},第三个}是包裹的结束标记。
2. C++代码修正方案
假设你之前的代码逻辑未正确处理大括号转义(}})和包裹结束的判断,以下是修正后的核心解析代码:
#include <string> #include <unordered_map> #include <cctype> std::unordered_map<std::string, std::string> parseOdbcConnStr(const std::string& connStr) { std::unordered_map<std::string, std::string> params; size_t pos = 0; const size_t strLen = connStr.size(); while (pos < strLen) { // 跳过前导空格 while (pos < strLen && isspace(connStr[pos])) pos++; if (pos >= strLen) break; // 提取关键字(到等号为止) size_t eqPos = connStr.find('=', pos); if (eqPos == std::string::npos) break; std::string key = connStr.substr(pos, eqPos - pos); pos = eqPos + 1; // 跳过关键字后的空格 while (pos < strLen && isspace(connStr[pos])) pos++; if (pos >= strLen) break; std::string value; if (connStr[pos] == '{') { // 处理大括号包裹的特殊值 pos++; // 跳过起始{ while (pos < strLen) { if (connStr[pos] == '}') { // 检查是否是转义的}} if (pos + 1 < strLen && connStr[pos + 1] == '}') { value += '}'; pos += 2; // 跳过两个连续的} } else { // 单个},结束包裹 pos++; break; } } else { value += connStr[pos]; pos++; } } } else { // 处理普通值(到分号或字符串结尾) size_t semicolonPos = connStr.find(';', pos); if (semicolonPos == std::string::npos) { value = connStr.substr(pos); pos = strLen; } else { value = connStr.substr(pos, semicolonPos - pos); pos = semicolonPos + 1; } } // 去除值的前后空格(符合ODBC非包裹值的空格处理规则) size_t valStart = value.find_first_not_of(" \t"); size_t valEnd = value.find_last_not_of(" \t"); if (valStart != std::string::npos) { params[key] = value.substr(valStart, valEnd - valStart + 1); } else { params[key] = ""; } } return params; }
核心修正点
- 新增
}}转义逻辑:遇到}时先检查下一个字符是否也是},是则转义为单个}加入值内容,否则判定为包裹结束 - 严格遵循ODBC解析顺序:先提取关键字,再根据值的开头字符选择对应解析逻辑
- 处理了前后空格的情况,符合规范中非包裹值的空格处理要求
测试验证:
- 输入
PWD={a{b}}};c};,解析出的PWD值为a{b}};c,符合预期 - 输入原格式
PWD={a{b}};c};,解析出的PWD值为a{b},剩余字段因无有效关键字被忽略
内容的提问来源于stack exchange,提问作者rahman
相关产品推荐
相关产品推荐

