鑑於EVAL一個公式:其值從列表替換變量名的字符串,並避免重複替換
eval_str = 'VAR1 > 0 and VAR1 < 10 and (VAR2 == VAR1::VALUE_X or VAR2 == VAR2::VALUE_X)'
任務:我需要更換變量(VAR1,VAR2在這個例子中),與它們的實際值,並用引號圍繞給定的「常量」(VAR1 :: VALUE_X)。
問題:由於變量名稱存在於常量和eval字符串中,並且由於變量可能被包含變量名稱的字符串替換 - 我遇到了常量值中的變量名稱由另一個常量或變量值替換。更好地顯示...
eval_str = '(VAR2 == VAR2::VALUE_X or VAR2 != VAR2::VALUE_Z) and (VAR1 > 0 and VAR1 < 10)'
var_dict = {'VAR1':'5','VAR2':'VAR1::VALUE_Y'}
# what I do is strip out most of the special characters
# the following findall = ['VAR1', '0', 'and', 'VAR1', '10', 'and', 'VAR2', 'VAR1::VALUE_X', 'or', 'VAR2', 'VAR2::VALUE_X']
for x in re.findall('[^\s()<>=!]+',eval_str):
# skip digits, and, or, None *need to improve regex
if x.replace('.','').isdigit() or x == 'and' or x == 'or' or x == 'None':
continue
# if variable is in dict
if x in var_dict.keys():
# only replace first
eval_str = eval_str.replace(x,var_dict[x],1)
# if is constant
elif x.__contains__('::'):
eval_str = eval_str.replace(x,'\'%s\''%x,1)
print eval_str
# (5::VALUE_Y == '5::VALUE_Y::VALUE_X' or VAR2 != 'VAR2::VALUE_Z') and (VAR1 > 0 and VAR1 < 10)
而不是通過每一個變量/值遞增的,也許會有更好的使用正則表達式爲每一個全部更換?或者,如果在每次更換後有記住字符串中的位置的方法,我是否可以修復現有的解決方案?
TYVM!
這應該是解析器的一部分? – 2012-07-10 13:21:01
這些是來自以前框架的驗證字符串,它們假設只是傳遞給eval()調用,但現在我必須注入實際值,因爲變量不再適用。 – breakbadjames 2012-07-10 14:21:01