Python多行正则提取表结构:含可选聚类顺序的4个分组需求
解决CREATE TABLE语句的多分组正则提取问题
我来帮你搞定这个从CREATE TABLE语句里提取指定分组的正则问题!针对你需要的四个提取目标——表名、表列定义、主键值、可选的聚类顺序值,我整理了一个适配多行场景的Python正则方案,还解决了嵌套主键括号和可选聚类顺序的捕获问题。
核心思路
首先明确CREATE TABLE的典型结构(以Cassandra语法为例,因为CLUSTERING ORDER是它的特性):
CREATE TABLE [IF NOT EXISTS] 表名 (
列定义1,
列定义2,
PRIMARY KEY ((分区键1, 分区键2), 聚类键1)
) [WITH CLUSTERING ORDER BY (聚类键1 DESC, 聚类键2 ASC)];
我们需要用正则精准捕获:
- 表名(支持带键空间的格式,比如
keyspace.table_v1) - 第一个括号内的所有列定义(到PRIMARY KEY之前的内容)
- PRIMARY KEY括号内的完整内容(包括嵌套的分区键括号)
- 可选的CLUSTERING ORDER括号内的排序规则
完整代码实现
import re # 定义多行正则模式,使用VERBOSE格式方便阅读,DOTALL让.匹配换行符 create_table_pattern = re.compile(r''' ^CREATE TABLE\s+ (?:IF NOT EXISTS\s+)? # 可选的IF NOT EXISTS子句 ([\w.]+)\s* # 分组1:表名,支持键空间.表名格式 \((.*?)\s* # 分组2:表列定义,匹配到PRIMARY KEY前的内容 PRIMARY KEY\s*\( ((?:[^()]|\((?:[^()]|\([^()]*\))*\))*) # 分组3:主键值,支持嵌套括号 \)\s* \) (?:\s+WITH CLUSTERING ORDER BY\s*\((.*?)\))? # 分组4:可选的聚类顺序值 \s*;$ ''', re.VERBOSE | re.DOTALL) # 测试示例1:带聚类顺序的CREATE TABLE语句 test_sql_1 = ''' CREATE TABLE user_profiles_v1 ( user_id UUID, username TEXT, join_date TIMESTAMP, PRIMARY KEY ((user_id), join_date) ) WITH CLUSTERING ORDER BY (join_date DESC); ''' # 测试示例2:不带聚类顺序的CREATE TABLE语句 test_sql_2 = ''' CREATE TABLE product_catalog ( product_id INT, product_name TEXT, price DECIMAL, PRIMARY KEY (product_id) ); ''' # 匹配并提取结果 def extract_table_info(sql: str): match = create_table_pattern.match(sql.strip()) if not match: return None return { "table_name": match.group(1), "columns": match.group(2).strip(), "primary_key": match.group(3).strip(), "clustering_order": match.group(4).strip() if match.group(4) else None } # 打印测试结果 print("测试示例1结果:") info1 = extract_table_info(test_sql_1) for k, v in info1.items(): print(f"- {k}: {v if v is not None else '无'}") print("\n测试示例2结果:") info2 = extract_table_info(test_sql_2) for k, v in info2.items(): print(f"- {k}: {v if v is not None else '无'}")
关键细节说明
re.DOTALL:让正则中的.匹配换行符,完美适配多行的CREATE TABLE语句。re.VERBOSE:允许我们把正则写成多行带注释的格式,可读性大幅提升。- 嵌套主键括号处理:用
(?:[^()]|\((?:[^()]|\([^()]*\))*\))*这个模式来匹配主键内的嵌套括号,解决了普通非贪婪匹配无法正确捕获嵌套内容的问题。 - 可选聚类顺序:用
(?:...)非捕获组包裹CLUSTERING ORDER部分,并加?标记为可选,确保不带聚类顺序的语句也能正常匹配。
运行输出
测试示例1结果: - table_name: user_profiles_v1 - columns: user_id UUID, username TEXT, join_date TIMESTAMP, - primary_key: (user_id), join_date - clustering_order: join_date DESC 测试示例2结果: - table_name: product_catalog - columns: product_id INT, product_name TEXT, price DECIMAL, - primary_key: product_id - clustering_order: 无
内容的提问来源于stack exchange,提问作者user2616355
相关产品推荐
相关产品推荐

