Dla rozwiązania bez użycia eval, oto co bym zrobił. Zacznij od znalezienia wszystkich wyrażeń matematycznych w ciągu, których będę zdefiniować jako ciąg znaków, który zawiera spacje, nawiasy, cyfry i operacje, a następnie rozebrać się mecze, które są wszystkie spacje:
>>> import re
>>> my_str = 'I have 6 * (2 + 3) apples'
>>> exprs = list(re.finditer(r"[\d\.\s\*\+\-\/\(\)]+", my_str))
>>> exprs = [e for e in exprs if len(my_str[e.start():e.end()].strip()) > 0]
Następnie ocenić wyrażenia wykorzystujące klasę NumericStringParser
z this question, który korzysta pyparsing:
>>> nsp = NumericStringParser()
>>> results = [nsp.eval(my_str[e.start():e.end()]) for e in exprs]
>>> results
[30.0]
Następnie, aby zastąpić wyniki z powrotem do wyrażenia, odwrócenie sortowania wyrażeń przez ich indeksu początkowego i umieścić je z powrotem do oryginalnego napisu:
>>> new_str = my_str
>>> for expr, res in sorted(zip(exprs, results), key=lambda t: t[0].start(), reverse=True):
... new_str = new_str[:expr.start()] + (" %d " % res) + new_str[expr.end():]
...
>>> new_str
'I have 30 apples'
Czy to zadanie domowe? –
http://stackoverflow.com/questions/2371436/evaluating-a-mathematical-expression-in-a-string –
@jeffery_the_wind nie tak naprawdę w punkcie, ponieważ ten (w przeciwieństwie do tego) wymaga odrzucenia nie matematycznych części ciągu. –