如何用正则表达式提取SELECT查询的所有输出列名?
解决SQL输出列名的正则提取问题
我明白你现在的困扰——正则写不对,没法从这段SQL里准确揪出所有输出列名。别担心,咱们一步步来搞定它!
首先,先分析你的SQL结构:输出列分两种情况:
- 直接引用表字段:
"table_name"."prop_id",需要提取最后一个引号里的prop_id - 带别名的聚合字段:
COUNT(...) AS "total_count",需要提取AS后面引号里的total_count
你之前写的正则/SELECT[\s\S]*[AS](.*),[\s\S]*FROM/g问题出在太宽泛了,它只试图匹配AS后面的某一段,完全没覆盖不带AS的原始字段,也没法处理多个列的情况,自然得不到预期结果。
正确的正则方案
这里给你一个能精准匹配所有目标列名的正则,搭配简单的循环提取逻辑就行:
const sql = `SELECT "table_name"."prop_id", "table_name"."some_other_id", "table_name"."blueprint_id", COUNT("table_name"."id") AS "total_count", COUNT("table_name"."id") FILTER (WHERE "table_name"."is_primary" = true) AS "some_count", COUNT("table_name"."id") FILTER (WHERE "table_name"."is_primary" = false) AS "extra_count" FROM table_name`; // 核心正则:匹配两种列格式,捕获需要的名称 const columnRegex = /"([^"]+)"(?:\s+AS\s+"([^"]+)")?/g; const columnNames = []; let matchResult; // 遍历所有匹配结果 while ((matchResult = columnRegex.exec(sql)) !== null) { // 有别名就用别名,没有就用原始字段名 columnNames.push(matchResult[2] || matchResult[1]); } console.log(columnNames); // 输出正好是你要的:["prop_id", "some_other_id", "blueprint_id", "total_count", "some_count", "extra_count"]
正则拆解说明
咱们来拆解一下这个正则的逻辑,方便你理解和调整:
"([^"]+)":匹配任意双引号包裹的内容,捕获引号内的字符串(比如"prop_id"或者"table_name")(?:\s+AS\s+"([^"]+)")?:这是一个非捕获组(?:开头),用来匹配带别名的情况:\s+AS\s+:匹配AS前后的任意空格"([^"]+)":捕获别名的内容- 最后的
?表示这个组是可选的(对应不带AS的原始字段)
g:全局匹配标志,让正则遍历整个SQL字符串,找到所有符合的列
额外提示
如果你的SQL后续出现更复杂的情况(比如字段名里包含特殊字符、嵌套引号),这个正则可能需要微调,但针对你当前给出的SQL结构,它完全够用。
内容的提问来源于stack exchange,提问作者Mohan
相关产品推荐
相关产品推荐

