2012-02-06 70 views
2

鑑於exampleString = "[9+[7*3+[1+2]]-5]" 如何提取和存儲由[]括號括起來的元素,然後按順序對它們進行評估?存儲和評估嵌套字符串元素

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

是否需要創建一些嵌套列表?對不起,這有點廣泛問題和糟糕的英語。

我看,這個問題實在太廣泛了......有沒有一種方法可以從該字符串創建嵌套列表?或者,也許我應該簡單地做每個元素的正則表達式搜索並評估每個元素?嵌套列表選項(如果存在的話)將是一種IMO「更乾淨」的方法,而不是循環遍歷相同的字符串並評估直到沒有[]括號。

+2

如果您不需要的中間值,一個簡單的查找/替換,輪流支架插入括號,其次是一個eval,將正常工作。 – Triptych 2012-02-06 14:58:19

+0

我沒有看到英語的重大問題。 (不重要的問題包括小寫專有名詞和不以問號結束的問題。)我無法直接回答您的問題,但我建議您搜索*解析工具*。 (Python解析工具,如果你喜歡,但你的例子不是特定於Python。) – kojiro 2012-02-06 15:02:01

+0

做一個快速評估,你可以簡單地做:'eval(exampleString.replace('[','(').replace(' ]',')'))' – juliomalegria 2012-02-06 15:05:27

回答

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) 

(編輯延長我的答案)

+0

謝謝,這將是一個有用的直接代碼。我認爲這可能也是與嵌套列表形成對比的最簡單方法。 – Firebowl2000 2012-02-06 17:09:20

2

一個好的起點是shunting-yard algorithm

在線提供了多種Python實現;這裏是one

該算法可用於將中綴表示法轉換爲各種表示形式。如果您不關心可以使用哪種表示形式,我建議考慮Reverse Polish notation,因爲它很容易處理。

3

看看pyparsing模塊和他們的一些例子(four function calculator是你想要的東西和更多)。

PS。如果代碼的大小令您擔心,請再看一遍:大部分代碼都可以被剝離。下半部分只是測試。上面的部分可以從支持e/pi/...常量,三角函數等東西中剝離出來。我相信你可以將它裁減到10行,以滿足你的需要。

+1

我要第二次pyparsing,它是_exactly_你需要開始這個。你想寫的不是解析器,而是(上下文無關)語言的語法。對我而言,這筆錢非常值得,入門指南http://shop.oreilly.com/product/9780596514235.do有助於快速入門。 – Hooked 2012-02-06 15:07:03

+1

看起來很多有用的東西可以在[pyparsing](http://pyparsing.wikispaces.com/)模塊中找到。該特定的[四功能計算器](http://pyparsing.wikispaces.com/file/view/fourFn.py)對於基本的數學表達式和eval()更安全的替代方法非常有用。此外,[nested.py](http://pyparsing.wikispaces.com/file/view/nested.py)中顯示的示例似乎將嵌套標記轉換爲**嵌套列表**。謝謝 – Firebowl2000 2012-02-06 17:25:36