2011-09-14 11 views
0

私はあるプラットフォームから別のプラットフォームにSQLを移行しています。 SQLには、ターゲットプラットフォームでサポートされていないDECODE文が含まれています。Pythonのネストされた正規表現置換

私は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 

と意志でデコードのすべてのオカレンスにマッチしますcase文で置き換えてください:

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文でデコード文のすべてを置き換えることができるように他の人の前に、最も内側のデコードを処理する方法はありますか?

+0

Hmmm ... Oracleとは何ですか? – NullUserException

+0

どちらのデータベースもOracle:D –

+0

興味深いものです。どのDBがOracle以外にも 'DECODE'をサポートしていますか? – NullUserException

答えて

1

デコードステートメントのすべてをケースステートメントに置き換えることができるように、最も内側のデコードを処理する方法はありますか?

はい。

(.*?)の代わりに((?![^)]*decode).*?)を使用して、ネストしたDECODEが合法的に発生する可能性があります。正規表現をループで実行します。

"decode"という文字列が含まれている文字列(「THEN値」など)があると、これが失敗する可能性があることに注意してください。あなたのデータを知っていて、このケースを除外することができれば、上の正規表現のアプローチはあなたの一回限りの使用のために十分です。