python中嵌套的正则表达式替换

时间:2011-09-14 18:19:49

标签: python sql regex string parsing

我正在将SQL从一个平台迁移到另一个平台。 SQL包含DECODE语句,我的目标平台不支持。

我正在使用正则表达式将解码语句转换为case语句,但我在嵌套解码时失败了:

import re
sql_frag = "select decode(dim1,'','-',dim1) as myfield1, decode(dim2,'','-',dim2') as myfield2"
reg=re.compile("(decode\((.*?),(.*?),(.*?),(.*?)\))",re.IGNORECASE)

matches = reg.findall(sql_frag)
for match in matches:
sql_frag = sql_frag.replace(match[0],'case when %s = %s then %s else %s end' % (match[1],match[2],match[3],match[4]))

将匹配

中出现的所有解码
select decode(dim1,'','-',dim1) as myfield1, decode(dim2,'','-',dim2') as myfield2

并将替换为案例陈述:

select case when dim1 = '' then '-' else dim1 end as myfield1, case when dim2 = '' then '-' else dim2' end as myfield2

但代码在嵌套解码语句中绊倒了:

sql_frag="select decode(f1,3,4,decode(f2,5,4,f2)) as myfield, decode(foo,bar,baz,foo) as myfield2"

>>> reg.findall(sql_frag)
[('decode(f1,3,4,decode(f2,5,4,f2)', 'f1', '3', '4', 'decode(f2,5,4,f2'), ('decode(foo,bar,baz,foo)', 'foo', 'bar', 'baz', 'foo')

并返回

select case when f1 = 3 then 4 else decode(f2,5,4,f2 end) as myfield, case when foo = bar then baz else foo end as myfield2

有没有办法在其他解码之前处理最里面的解码,这样我就可以用case语句干净地替换所有的解码语句?

1 个答案:

答案 0 :(得分:1)

  

有没有办法在其他解码之前处理最里面的解码,这样我就可以用case语句干净地替换所有的解码语句?

使用((?![^)]*decode).*?)代替合法发生嵌套(.*?)的任何DECODE。循环运行正则表达式。

请注意,如果存在包含单词“decode”的字符串(即“THEN值”),则此操作可能会失败。如果您知道自己的数据并且可以排除这种情况,那么上述正则表达式方法对于您的一次性用例就足够了。