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

Python正则匹配SQL脚本中CTAS语句并保留注释的改造需求

保留注释的CTAS语句识别与改造方案

核心思路

不要先全局移除注释,而是先标记脚本中的所有注释区域(单行、多行),仅在非注释区域匹配并改造CTAS语句,最后将原注释和改造后的代码按原顺序合并,确保注释完全保留。

具体实现步骤

  • 识别注释与字符串区域:用正则匹配单行注释(--到行尾)、多行注释(/* ... */)以及字符串(单/双引号包裹内容),避免误将字符串内的注释符号判定为注释。
  • 分割与处理脚本:将脚本拆分为注释段、字符串段和非注释段,只对非注释段执行CTAS匹配和改造。
  • 匹配CTAS语句:编写覆盖常见语法的正则(如支持临时表、IF NOT EXISTS、大小写不敏感),定位需要改造的CTAS语句并执行修改。
  • 合并内容:将处理后的非注释段与原注释段、字符串段按原顺序拼接,输出完整脚本。

示例Python代码

import re

def process_ctas_preserve_comments(sql_script):
    # 正则:匹配多行注释、单行注释、字符串(优先匹配,避免误判)
    pattern = re.compile(
        r'(/\*.*?\*/)|(--[^\n]*(\n|$))|(\'[^\']*?\'|"[^"]*?")',
        re.DOTALL | re.IGNORECASE
    )
    processed_parts = []
    current_pos = 0

    for match in pattern.finditer(sql_script):
        # 处理匹配前的非注释内容
        if match.start() > current_pos:
            non_comment_segment = sql_script[current_pos:match.start()]
            # 改造非注释区域的CTAS:示例为表名添加后缀_NEW
            modified_segment = re.sub(
                r'CREATE\s+(TEMPORARY|TEMP)?\s*(IF NOT EXISTS)?\s*TABLE\s+(\w+)\s+AS\s+(SELECT.*?)(?=\s*(;|CREATE|$))',
                r'CREATE \1\2 TABLE \3_NEW AS \4',
                non_comment_segment,
                flags=re.DOTALL | re.IGNORECASE
            )
            processed_parts.append(modified_segment)
        # 添加原注释或字符串内容(不修改)
        processed_parts.append(match.group())
        current_pos = match.end()

    # 处理最后一段非注释内容
    if current_pos < len(sql_script):
        final_non_comment = sql_script[current_pos:]
        modified_final = re.sub(
            r'CREATE\s+(TEMPORARY|TEMP)?\s*(IF NOT EXISTS)?\s*TABLE\s+(\w+)\s+AS\s+(SELECT.*?)(?=\s*(;|CREATE|$))',
            r'CREATE \1\2 TABLE \3_NEW AS \4',
            final_non_comment,
            flags=re.DOTALL | re.IGNORECASE
        )
        processed_parts.append(modified_final)

    return ''.join(processed_parts)

# 测试用例
test_sql = """
-- 初始化表
CREATE TABLE t1 AS SELECT id, name FROM raw_data;

/* 临时表用于中间计算
支持跨多行的CTAS */
CREATE TEMP TABLE temp_data AS SELECT id, SUM(value) FROM raw_data GROUP BY id;

CREATE TABLE t2 AS SELECT * FROM temp_data; -- 这是语句末尾的注释
"""

print(process_ctas_preserve_comments(test_sql))

关键注意事项

  • 正则优先级:必须优先匹配字符串和注释,防止把字符串内的--或/*误判为注释。
  • 语法兼容性:CTAS正则要覆盖SQL的常见变体,比如临时表关键字、IF NOT EXISTS、换行写法等。
  • 边界处理:注意CTAS语句的结束边界(分号、下一个CREATE语句或脚本结尾),避免匹配不完整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 22:35:18