ネストされた文字列要素の格納と評価

exampleString = "[9+ [7 * 3 + [1 + 2]] -5" " どのように[]で囲まれた要素を抽出して格納し、それを順番に評価するのですか?

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

ネストされたリストのいくつかを作成する必要がありますか? 広範な質問と悪い英語を多少残して申し訳ありません。

私は、この質問は本当に広すぎると思う...その文字列からネストされたリストを作成する方法はありますか?または、単に各要素の正規表現検索を行い、それぞれを評価する必要がありますか?ネストされたリストオプション(存在する場合)は、同じ文字列をループし、theresがなくなるまで評価するよりも、よりクリーンな方法です。

2
私は英語に大きな問題はないと思う。質問に直接答えることはできませんが、解析ツールを検索することをおすすめします。 (好きな場合はPythonの解析ツールですが、あなたの例はPython固有のものではありません)。
追加された 著者 kojiro,
中間の値を必要としない場合は、大かっこを括弧に変換し、その後に評価を付ける簡単な検索/置換がうまくいきます。
追加された 著者 Triptych,
数式を文字列で評価すると関連しているようです。 unutbuの回答をご覧ください。
追加された 著者 Rik Poggi,
eval(exampleString.replace( '['、 '(').replace( ']'、 ')'))
追加された 著者 juliomalegria,

3 答え

pyparsing モジュールとそのサンプル( 4つの関数電卓は、あなたが望むものなどです。

PS。そのコードのサイズが心配している場合は、もう一度見てください:これのほとんどは取り除くことができます。下半分は単なるテストです。上部は、e/pi/...定数、三角関数などをサポートするようなものからはずすことができます。必要なものを10行に減らすことができます。

3
追加された
私は2番目のpyparsingに行くつもりです、それは正確にこれを始めるために必要なものです。あなたが書いたいのはパーサではなく、(文脈自由な)言語の文法です。私にとっては価値があり、入門ガイドは shop.oreilly.com/product/9780596514235 .do はすぐに開始するのに役立ちました。
追加された 著者 Hooked,
pyparsing モジュールには多くの便利な機能があります。その特定の 4関数計算機は、基本的な数式の表現には非常に便利で、 eval()の代わり。また、 nested.py に表示されている例は、ネストされたタグを< b>入れ子リスト]をクリックします。ありがとう
追加された 著者 Firebowl2000,

良い出発点はシャントヤードアルゴリズムです。

オンラインで利用できるPythonの実装は複数あります。 1つです。

このアルゴリズムは、中置表記を様々な表現に翻訳するために使用することができる。どの表現が使用できるかについて制約がない場合は、逆ポーランド語記法作業が簡単です。

2
追加された

ここに正規表現の解決策があります:

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)

(私の答えを拡張するために編集された)

1
追加された
ありがとう、それは便利なコードです。ネストされたリストとは対照的に、これが最も簡単にアプローチできると思います。
追加された 著者 Firebowl2000,