拆分逗号分隔的字符串,同时转义括号中的字符串

时间:2014-09-15 18:32:58

标签: python csv ddl comma

我在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模块,但仍然没有逃避值中的嵌入式逗号。正则表达式是唯一的出路吗?

2 个答案:

答案 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)