我正在编写一个python脚本,它将方程式作为文本字符串读取并对其求值。这些方程很长(几百个字符),并且具有多个括号。此外,还有嵌套条件。例如:
str =“ A *((B + 7> = 0)?((D *(E +(F)/ sqrt((W)(R)/ C ((S)- 2 3 +(((max(S,6)> Z?U + I:V + T)))))/ R))):((sqrt(D)(E +(F)/ sqrt((9)(R)/ C ((S)-2 * 3 +((S> Z?max(U,X)+ I:V + T))))))/ R)/ sqrt(W)))“
我删除所有空格以使其更易于解析
我蛮力强制执行以下代码:
str = "A*((B+7>=0)?((D*(E+(F)/sqrt((W)*(R)/C*((S)-2*3+((max(S,6)>Z?U+I:V+T)))))/R)):((sqrt(D)*(E+(F)/sqrt((9)*(R)/C*((S)-2*3+((S>Z?max(U,X)+I:V+T)))))/R)/sqrt(W)))"
operators = ['+','-','/','*','?',':']
functions = ['sqrt','max']
def ternAround(eqn):
# this function replaces ?: ternary operators with python if else operators
# eqn is an equation text string
done = 0
while not done:
str = eqn.split("?",1)
if len(str) > 1:
# get term to left of ?
A = str[0]
astop = len(A)
i = astop-1
pct = 0
while i >= 0 and pct!=1:
# find first unpaired "("
pct = pct+1 if A[i]=="(" else pct-1 if A[i]==")" else pct
i = i-1
A = A[i+2:] if pct==1 else A
astart = i+2 if pct==1 else 0
#print(A,astart,astop)
# get term between ? and :
B = str[1]
bstart = 0
pct = 0
i = 0
while i < len(B):
# find first : outside of paired "()"
if B[i] == ":" and pct==0:
bstop = i
B = B[bstart:bstop]
break
pct = pct+1 if B[i]=="(" else pct-1 if B[i]==")" else pct
i = i+1
#print(B,bstart,bstop)
# get term to right of :
cstart = bstop + 1
C = str[1][cstart:]
pct = 0
i = 0
while i < len(C) and pct!=-1:
# find first unpaired "("
pct = pct+1 if C[i]=="(" else pct-1 if C[i]==")" else pct
i = i+1
C = C[:i-1] if pct==-1 else C
cstop = i-1 if pct==-1 else len(C)
#print(C,cstart,cstop)
bstart = bstart + astop + 1
bstop = bstart + bstop
cstart = cstart + astop + 1
cstop = cstart + cstop
eqn = ''.join([eqn[:astart],B," if ",A," else ",C,eqn[cstop:]])
done = 0
else:
done = 1
return(eqn)
print(ternAround(str))
结果:
A *((((D *(E +(F)/ sqrt((W)(R)/ C ((S)-2 3 +((U + I if max(S,6)> Z else V + T))))))/ R))如果(B + 7> = 0)else((sqrt(D)(E +(F)/ sqrt(( 9)(R)/ C ((S)-2 * 3 +((如果S> Z否则V + T))()max)(R)/ sqrt(W)))
我觉得使用正则表达式可能会有一种更为优雅的方法。这里的某人可能可以用两三行代码来做到这一点。