我在values.e.x中也收到带有嵌入式逗号的SQL DDL字符串。
org_id bigint,merc_name varchar(50),deposit_day date null,amount decimal(18,3),bank_name varchar(128)
这些SQL字符串值是从我们从其他应用程序收到的DDL文件中提取的(因此,我们目前无法要求其他团队从其末端修复它以逃避嵌入式逗号)。我们希望输出为:
['org_id bigint', 'merc_name varchar(50)', 'deposit_day date null', 'amount decimal(18,3)', 'bank_name varchar(128)']
我尝试了csv模块,但仍然没有逃避值中的嵌入式逗号。正则表达式是唯一的出路吗?
答案 0 :(得分:2)
Tokenize并使用最简单的状态机;这不会处理嵌套的括号,但对于这种情况就足够了:
import re
def parse_sql_ddl(ddl):
tokens = iter(re.findall('(\w+|[,() ])', ddl))
current = []
for token in tokens:
if not token: continue # zero-width start or end
if token == ',':
yield ''.join(current)
current = []
elif token == '(':
current.append(token)
for token in tokens:
current.append(token)
if token == ')':
break
else:
current.append(token)
if current:
yield ''.join(current)
将您的输入解析为标记(字符,或逗号,括号和空格,然后生成完整的列声明:
>>> sample = 'org_id bigint,merc_name varchar(50),deposit_day date null,amount
decimal(18,3),bank_name varchar(128)'
>>> for column in parse_sql_ddl(sample):
... print column
...
org_id bigint
merc_name varchar(50)
deposit_day date null
amount decimal(18,3)
bank_name varchar(128)
您可以扩展解析器以处理错误条件(当逗号有空时current
为空,或者在找到结束)
之前用尽令牌等)。它也可以很容易地扩展到处理引用的名称(也可能包含括号和逗号!),再次添加一个嵌套循环,就像处理括号一样。
答案 1 :(得分:2)
使用正则表达式:
ddl = 'org_id bigint,merc_name varchar(50),deposit_day date null,amount decimal(18,3),bank_name varchar(128)'
print re.findall('(?:[^,(]|\(.*?\))+', ddl)