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

PostgreSQL SQL查询动态参数对应列的正则匹配问题求助

问题分析与正则修正方案

原代码存在几个核心问题:

  • 正则匹配方向错误:findParamColumn 里的正则逻辑是从列找参数,而非从目标参数反向匹配对应列
  • 运算符转义错误:误用HTML实体(<等)替代正则可识别的原生运算符符号
  • IN子句处理失效:原正则无法正确匹配column IN ($param)这类场景
  • 结果映射逻辑颠倒:findParamsColumns 把列名作为键、参数作为值,与需求完全相反
  • 单词边界\b失效:$是非单词字符,\b$g1\b无法正确定位参数的边界

修正后的代码

function findParamColumn(query, param) {
  // 转义参数中的正则特殊字符(比如$),避免正则语法错误
  const escapedParam = param.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  
  // 正则覆盖三种目标场景:
  // 1. 列名 + 比较运算符 + 动态参数
  // 2. 动态参数 + 比较运算符 + 列名
  // 3. 列名 + IN + (包含目标参数的括号内容)
  const regex = new RegExp(
    `(?:\\b([a-z_]+)\\b\\s*(?:[<>]=?|!=|<>|=|IN)\\s*${escapedParam})|(?:${escapedParam}\\s*(?:[<>]=?|!=|<>|=)\\s*\\b([a-z_]+)\\b)|(?:\\b([a-z_]+)\\b\\s*IN\\s*\\([^)]*${escapedParam}[^)]*\\))`,
    'gi'
  );
  
  const columns = [];
  let match;
  while ((match = regex.exec(query)) !== null) {
    // 提取三个捕获组中不为空的列名
    const column = match[1] || match[2] || match[3];
    if (column) {
      columns.push(column.toLowerCase()); // 统一小写避免SQL大小写差异问题
    }
  }
  return [...new Set(columns)]; // 对列名去重
}

function findParamsColumns(query) {
  // 提取所有$开头的动态参数并去重
  const paramRegex = /\$\w+/g;
  const params = [...new Set(query.match(paramRegex) || [])];

  const paramsColumns = {};
  for (const param of params) {
    const columns = findParamColumn(query, param);
    // 根据列数自动返回字符串或数组,匹配示例格式
    paramsColumns[param] = columns.length === 1 ? columns[0] : columns;
  }
  return paramsColumns;
}

关键修正点说明

  1. 多场景正则覆盖:

    • 用三个捕获组分别处理参数在运算符两侧、以及IN子句中的情况
    • 运算符集合[<>]=?|!=|<>|=覆盖了PostgreSQL常用的比较运算符
    • 针对IN子句加入\([^)]*${escapedParam}[^)]*\),确保能捕获括号内包含目标参数的语句
  2. 参数转义处理:

    • 新增escapedParam处理,将参数中的正则特殊字符(如$)转义,避免正则语法解析错误
  3. 结果格式优化:

    • 对匹配到的列名去重、统一小写,避免重复记录或大小写差异问题
    • 根据列的数量自动返回字符串或数组,完全符合示例要求的输出格式

测试验证

用你给出的示例测试:

  1. 输入:SELECT * from Students where grade > $g1 and grade < $g2 and grade < $g3
    返回:{ $g1: 'grade', $g2: 'grade', $g3: 'grade' }
  2. 输入:SELECT * from Students where age > $g1 and grade < $g1
    返回:{ $g1: ['age', 'grade'] }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:45:30