You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Python re模块提取文本中所有多行SQL SELECT语句块

如何使用Python re模块提取文本中所有多行SQL SELECT语句块

我来帮你搞定这个提取多行SELECT块的问题!用正则处理SQL确实得注意各种细节,比如多行换行、带UNION的联合查询,还有不同的语句结尾方式(分号/括号),下面我一步步给你演示怎么做:

首先先明确我们要覆盖的几种场景:

  • 单行的简单SELECT语句(比如select p.value_n, p.enabled from proper p;
  • 跨多行、带WHERE条件的SELECT语句
  • 被括号包裹的联合查询块(比如(select ... union all select ...)

直接上可运行的代码,我会逐段解释:

import re

# 你的原始SQL文本
sql_que = """
select p.value_n, p.enabled from proper p;

select p.value_n, p.enabled    
    from proper p
   where p.property_name = 'PROP1';
   
(select p.value_n, p.enabled    
    from proper p
   where p.property_name = 'PROP1'
   union all
select p.value_n, p.enabled    
    from proper p
   where p.property_name = 'PROP2'
)
"""

# 核心正则表达式
# 拆解下这个pattern的关键部分:
# (?i):忽略大小写,不管是大写SELECT还是小写select都能匹配
# (?:...):非捕获组,把两种匹配规则打包,不会单独返回组内的子匹配
# \(select.*?\):匹配括号包裹的SELECT块,从(select开始到对应的)结束
# |:逻辑或,匹配后面的普通SELECT语句规则
# select.*?;:匹配从select开头到分号结束的常规SELECT语句
# re.DOTALL:让正则中的.能匹配换行符,这样多行内容也能被完整捕获
pattern = r'(?i)(?:\(select.*?\)|select.*?;)'
matches = re.findall(pattern, sql_que, flags=re.DOTALL)

# 清理匹配结果:把多余的换行、连续空格换成单个空格,让输出更整洁
cleaned_selects = []
for match in matches:
    # 先去除语句前后的空白字符
    stripped_stmt = match.strip()
    # 把所有连续的空白(换行、空格、制表符)统一换成单个空格
    cleaned_stmt = re.sub(r'\s+', ' ', stripped_stmt)
    cleaned_selects.append(cleaned_stmt)

# 打印提取结果
for idx, stmt in enumerate(cleaned_selects, 1):
    print(f"第{idx}个SELECT块:")
    print(stmt)
    print("-" * 50)

运行这段代码后,你会得到三个完整的SELECT块,包括那个带UNION ALL的联合查询,完全符合你的需求!

最后提个小提醒:这个正则是针对你的示例场景写的,如果你的实际SQL里有嵌套括号(比如SELECT里的子查询还有多层括号),或者字符串里包含分号/括号(比如WHERE name = 'abc;def'),那这个简单正则就会失效——毕竟正则没法真正理解SQL语法,只能做模式匹配。

如果你的实际场景更复杂,比如有嵌套子查询、字符串内的特殊符号,我更推荐用专门的SQL解析库sqlparse,它能真正读懂SQL语法,比正则靠谱多了。但如果你的场景和示例一样简单,上面的正则完全够用啦!

火山引擎 最新活动