存储和评估嵌套的字符串元素

时间:2012-02-06 14:56:43

标签: python parsing

鉴于exampleString = "[9+[7*3+[1+2]]-5]" 如何提取和存储由[]括号括起来的元素,然后按顺序对它们进行评估?

1+2 --+
      |
  7*3+3 --+
          |
        9+24-5

是否必须创建一些嵌套列表?很抱歉这个有点广泛的问题和糟糕的英语。

我知道,这个问题实在太宽了......有没有办法从该字符串创建嵌套列表?或者也许我应该只是对每个元素进行正则表达式搜索并评估每个元素?嵌套列表选项(如果存在)将是一种IMO“更清洁”的方法,而不是循环遍历相同的字符串并进行评估,直到没有[]括号。

3 个答案:

答案 0 :(得分:3)

查看pyparsing模块及其中的一些示例(four function calculator是您想要的内容以及更多内容。)

PS。如果该代码的大小让您担心,请再次查看:大部分内容都可以删除。下半部分只是测试。上部可以剥离支持e / pi / ...常数,三角函数等等。我相信你可以将它减少到10行,以满足你的需要。

答案 1 :(得分:2)

一个很好的起点是shunting-yard algorithm

在线提供多种Python实现;这是one

该算法可用于将中缀表示法转换为各种表示法。如果您对可以使用的表示没有约束,我建议您考虑使用Reverse Polish notation,因为它很容易使用。

答案 2 :(得分:1)

这是一个正则表达式解决方案:

import re

def evaluatesimple(s):
  return eval(s)

def evaluate(s):
  while 1:
    simplesums=re.findall("\[([^\]\[]*)\]",s)
    if (len(simplesums) == 0):
      break
    replacements=[('[%s]' % item,str(evaluatesimple(item))) for item in simplesums]
    for r in replacements:
      s = s.replace(*r)
  return s

print evaluate("[9+[7*3+[1+2]]-5]")

但是如果你想要整个猪并建立一个树以便稍后评估,你可以使用相同的技术,但将表达式和子表达式存储在一个字典中:

def tokengen():
  for c in 'abcdefghijklmnopqrstuvwyxz':
    yield c

def makeexpressiontree(s):
  d=dict()
  tokens = tokengen()
  while 1:
    simplesums=re.findall("\[([^\]\[]*)\]",s)
    if (len(simplesums) == 0):
      break
    for item in simplesums:
      t = tokens.next()
      d[t] = item
      s = s.replace("[%s]"% item,t)
  return d

def evaltree(d):
  """A simple dumb way to show in principle how to evaluate the tree"""
  result=0
  ev={}
  for i,t in zip(range(len(d)),tokengen()):
    ev[t] = eval(d[t],ev)
    result = ev[t]
  return result

s="[9+[7*3+[1+2]]-5]"
print evaluate(s)
tree=makeexpressiontree(s)
print tree
print evaltree(tree)

(编辑扩展我的答案)