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

如何用Regex或JavaScript正确提取SQL查询中的关键信息?

提取SQL查询关键信息的可靠方案

问题背景

我们需要从SQL查询字符串中提取表名、筛选条件、Limit等关键信息,例如:
给定SQL语句:

const sql = "select * from products where id=1 and description like '%thick and crispy%'";

期望提取的筛选条件为:

const filters = ["id=1","description like '%thick and crispy%'"];

最初尝试用简单的正则拆分:

const filters = sql.split(/ and /gi);

但这种方式存在明显缺陷:当筛选条件的值本身包含and(比如示例里的%thick and crispy%)时,会错误拆分条件;同时还需要处理不区分大小写的SQL关键字、LIKE/OR/IN等多种子句,简单拆分完全无法满足需求。


解决方案

方案1:优化后的正则表达式

通过精准的正则匹配,避开字符串内部的关键字,正确拆分筛选条件。核心思路是先定位WHERE子句范围,再区分引号/括号内的内容和外部的逻辑运算符。

示例代码:

function extractFilters(sql) {
  // 提取WHERE到下一个关键字(或结尾)的内容
  const whereMatch = sql.match(/where\s+(.*?)(?=\s+(limit|order by|group by|$))/i);
  if (!whereMatch) return [];
  
  const whereClause = whereMatch[1];
  // 拆分条件,忽略引号、括号内的AND/OR
  const filterRegex = /([^'"()]+(?:\(['"](?:[^'"\\]|\\.)*['"]\))?)(?=\s+(and|or)\s+|$)/gi;
  const filters = [];
  let match;
  
  while ((match = filterRegex.exec(whereClause)) !== null) {
    filters.push(match[1].trim());
  }
  
  return filters;
}

// 测试复杂场景
const testSql = "select * from products where id=1 and description like '%thick and crispy%' or category in ('electronics', 'home and garden')";
console.log(extractFilters(testSql));
// 输出: ["id=1", "description like '%thick and crispy%'", "category in ('electronics', 'home and garden')"]

注意:正则仅适用于结构不复杂的SQL,遇到嵌套子查询、多层嵌套括号等场景时,依然可能出现解析错误。


方案2:使用专门的SQL解析库(推荐)

通过JavaScript的SQL解析库,将SQL转换为抽象语法树(AST),再从AST中提取所需信息,这是最可靠的方案,能处理几乎所有合法SQL语法。

以sql-parser-mysql为例(可通过npm直接安装),示例代码:

const parser = require('sql-parser-mysql');

function parseSQL(sql) {
  try {
    const ast = parser.parse(sql);
    const result = {
      tableName: ast.from[0].table,
      filters: [],
      limit: ast.limit ? ast.limit.value : null
    };

    // 遍历WHERE条件节点,提取筛选规则
    function traverseCondition(node) {
      if (node.type === 'binary_expr') {
        if (['AND', 'OR'].includes(node.operator.toUpperCase())) {
          // 递归处理AND/OR连接的子条件
          traverseCondition(node.left);
          traverseCondition(node.right);
        } else {
          // 拼接单个条件表达式
          const left = node.left.value;
          const operator = node.operator;
          let right = node.right.value;
          if (node.right.type === 'string') {
            right = `'${right}'`;
          }
          result.filters.push(`${left} ${operator} ${right}`);
        }
      } else if (node.type === 'function') {
        // 处理IN等函数式条件
        const args = node.args.map(arg => 
          arg.type === 'string' ? `'${arg.value}'` : arg.value
        ).join(', ');
        result.filters.push(`${node.name}(${args})`);
      }
    }

    if (ast.where) {
      traverseCondition(ast.where);
    }

    return result;
  } catch (err) {
    console.error('SQL解析失败:', err);
    return null;
  }
}

// 测试示例
const testSql = "select * from products where id=1 and description like '%thick and crispy%' limit 10";
const parsedResult = parseSQL(testSql);
console.log(parsedResult);
/* 输出:
{
  tableName: 'products',
  filters: [ 'id = 1', 'description like \'%thick and crispy%\'' ],
  limit: 10
}
*/

总结

  • 简单SQL场景:可以用优化后的正则快速实现需求
  • 复杂SQL场景:优先使用专门的SQL解析库,保证稳定性和兼容性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 17:12:50