Это похоже на проблему разбора, и поэтому я вынужден представить решение, основанное на методах разбора.
Хотя может показаться, что вы хотите «разбить» эту строку, я думаю, что вы на самом деле хотите «токенизировать» ее. Tokenization или lexxing - это этап компиляции перед синтаксическим анализом. Я исправил свой исходный пример в редакторе, чтобы реализовать правильный рекурсивный приличный парсер. Это самый простой способ реализовать парсер вручную.
import re
patterns = [
('number', re.compile('\d+')),
('*', re.compile(r'\*')),
('/', re.compile(r'\/')),
('+', re.compile(r'\+')),
('-', re.compile(r'\-')),
]
whitespace = re.compile('\W+')
def tokenize(string):
while string:
# strip off whitespace
m = whitespace.match(string)
if m:
string = string[m.end():]
for tokentype, pattern in patterns:
m = pattern.match(string)
if m:
yield tokentype, m.group(0)
string = string[m.end():]
def parseNumber(tokens):
tokentype, literal = tokens.pop(0)
assert tokentype == 'number'
return int(literal)
def parseMultiplication(tokens):
product = parseNumber(tokens)
while tokens and tokens[0][0] in ('*', '/'):
tokentype, literal = tokens.pop(0)
if tokentype == '*':
product *= parseNumber(tokens)
elif tokentype == '/':
product /= parseNumber(tokens)
else:
raise ValueError("Parse Error, unexpected %s %s" % (tokentype, literal))
return product
def parseAddition(tokens):
total = parseMultiplication(tokens)
while tokens and tokens[0][0] in ('+', '-'):
tokentype, literal = tokens.pop(0)
if tokentype == '+':
total += parseMultiplication(tokens)
elif tokentype == '-':
total -= parseMultiplication(tokens)
else:
raise ValueError("Parse Error, unexpected %s %s" % (tokentype, literal))
return total
def parse(tokens):
tokenlist = list(tokens)
returnvalue = parseAddition(tokenlist)
if tokenlist:
print 'Unconsumed data', tokenlist
return returnvalue
def main():
string = '2+24*48/32'
for tokentype, literal in tokenize(string):
print tokentype, literal
print parse(tokenize(string))
if __name__ == '__main__':
main()
Реализация обработки скобок оставлена в качестве упражнения для читателя. Этот пример будет правильно делать умножение перед сложением.