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

解析含特殊字符的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 12:30:42