2010-09-13 63 views
0

我有一個SQL字符串,例如更換字符串的某些部分與Python

SELECT * FROM benchmark WHERE xversion = 1.0 

而實際上,xversion的別名變量,self.alias擁有所有的別名信息像

 
{'CompilationParameters_Family': 'chip_name', 
'xversion': 'CompilationParameters_XilinxVersion', 'opt_param': 
    .... 
'chip_name': 'CompilationParameters_Family', 
'CompilationParameters_Device': 'device'} 

使用這個別名,我應該改變字符串爲如下。

SELECT * FROM benchmark WHERE CompilationParameters_XilinxVersion = 1.0 

對於這個改變,我想出了以下內容。

def processAliasString(self, sqlString): 
    components = sqlString.split(' ') 
    resList = [] 
    for comp in components: 
     if comp in self.alias: 
      resList.append(self.alias[comp]) 
     else: 
      resList.append(comp) 
    resString = " ".join(resList) 
    return resString 

但是,我希望更好的代碼不使用循環。你怎麼看?

+0

我可以在你的代碼中看到一個潛在的弱點。想想如果'self.alias'這樣說會發生什麼,就像這樣:'{'SELECT':'DROP','*':'TABLE','FROM':'','WHERE':'; - ' }'。 – 2010-09-13 02:45:10

回答

1

如果你可以改變你的輸入字符串的格式,使更換更加清晰可見,如

s = 'SELECT * FROM benchmark WHERE %(xversion)s = 1.0' 

然後s % self.alias就足夠了(有可根據自己喜歡的格式的語法和Python級別其他一些替代品)。

如果輸入的字符串格式是「固定的」,re可以提供幫助,因爲它容易識別字的邊界(所以如果沒有其他不重要的空間,例如在xversion)。考慮(具有s它原始的形式,與非substitutables混合隨意substitutables):

import re 
sre = re.compile('|'.join(r'\b%s\b' % re.escape(s) for s in self.alias)) 
def repl(mo): 
    return self.alias[mo.group()] 
news = sre.sub(repl, s) 

這些方法是快速的,因爲% -formatting和re S'sub都非常好這樣的任務進行了優化。

+0

感謝您的精彩提示。不幸的是,用戶給了我SQL命令,所以爲了使用你的代碼,我應該解析以確切地知道字符串的哪一部分應該被修改,這在現在實際上是不可能的。 – prosseek 2010-09-13 03:59:11

+0

@prosseek,然而,你可以在我的答案的第二部分使用基於're'的代碼(沒有失去微不足道空間的風險,就像'.split()'的方法一樣)。 – 2010-09-13 04:23:02

+0

我明白了,再次感謝您的幫助。 – prosseek 2010-09-13 14:35:59

1

這應做到:

def processAliasString(self, sqlString): 
    return ' '.join(self.alias.get(comp, comp) for comp in sqlString.split(' '))