
本文介绍一种基于正则表达式断言的 java 字符串分割方案,精准匹配“as”关键字后出现的逗号(忽略大小写),避免误切嵌套括号或函数内部的逗号,适用于解析多行 sql select 子句。
在 SQL 查询字符串解析场景中,常需将 SELECT 子句按列定义拆分为独立表达式。但直接使用 split(",") 会破坏含逗号的函数调用(如 DATE_TRUNC('month', timestamp))或窗口函数(如 OVER(PARTITION BY a, b ORDER BY c))。理想策略是:仅在 AS 关键字之后、作为列别名分隔符的逗号处切分。
Java 的 String.split() 不支持无限长度的 (?有限长度量词的兼容型正向后查找:
String[] queryArray = internalQuery.split(
"(?<=\\s{1,99}[aA][sS]\\s{1,99}\\w{1,99})\\s*,\\s*");✅ 正则详解:
- (?
- 1–99 个空白字符(兼容换行、缩进);
- 大小写不敏感的 AS([aA][sS]);
- 再跟 1–99 个空白字符;
- 最后是 1–99 个单词字符(即别名名称,如 month_begin_dt)。
⚠️ 注意事项:
- 别名长度上限设为 99 是权衡结果:既满足绝大多数真实 SQL 别名(通常
- 该正则不处理 AS 被引号包裹的情况(如 "AS" 或 'AS'),若 SQL 中存在带引号的关键字,需先预处理转义或升级为语法树解析(如 JSqlParser)。
- 输入字符串建议先 trim() 去除首尾空白,并确保换行符为 \n(Windows 环境下可先 .replace("\r\n", "\n"))。
? 验证示例:
对如下输入:
DATE_TRUNC('month', timestamp) AS month_begin_dt
, FIRST_VALUE(monitorsessionid) OVER(PARTITION BY openpsid,DATE_TRUNC('month', timestamp) ORDER BY timestamp DESC) AS monitorsessionid
, FIRST_VALUE(vrr) OVER(PARTITION BY openpsid,DATE_TRUNC('month', timestamp) ORDER BY timestamp DESC) AS vrr执行上述 split() 后,queryArray 将严格返回 3 个元素,每个元素均为完整、语义正确的列表达式,且保留原有缩进与换行格式,便于后续 SQL 构建或元数据提取。
总结:此方案以轻量正则实现高精度 SQL 片段分割,在工程实践中兼顾准确性、可读性与 JVM 兼容性,是处理类 SQL 字符串结构化解析的可靠起点。










