簡體   English   中英

如何在Python中評估自定義數學表達式

[英]How to evaluate a custom math expression in Python

我在python中編寫了一個自定義骰子滾動解析器(如果必須,可以使用snicker)。 基本上,我想使用標准數學評估,但添加'd'運算符:

#xdy
sum = 0
for each in range(x):
    sum += randInt(1, y)
return sum

所以,例如,1d6 + 2d6 + 2d6-72 + 4d100 =(5)+(1 + 1)+(6 + 2)-72+(5 + 39 + 38 + 59)= 84

我正在使用正則表達式來替換所有'和s,然后使用eval,但我的正則表達式在處理任何一方的括號時都崩潰了。 有沒有比實現我自己的遞歸解析更快的方法呢? 也許在eval中添加運算符?

編輯:我似乎給出了一個不好的例子,因為上面的例子適用於我當前的版本。 我正在尋找的是評估(5+(6d6))d(7-2 *(1d4))的一些方法。
通過“分崩離析”,我只是意味着我當前的正則表達式失敗了。 我對自己的失敗過於模糊,對此感到抱歉。 這是我目前的代碼:

def evalDice(roll_matchgroup):
    roll_split = roll_matchgroup.group('roll').split('d')
    print roll_split
    roll_list = []

    for die in range(int(roll_split[0])):
        roll = random.randint(1,int(roll_split[1]))
        roll_list.append(roll)

def EvalRoll(roll):
    if not roll: return 0
    rollPattern = re.compile('(?P<roll>\d*d\d+)')
    roll_string = rollPattern.sub(evalDice, roll.lower())

為此,“1d6 + 4d100”工作正常,但“(1d6 + 4)d100”或甚至“1d6 + 4d(100)”失敗。

你可以使用re.sub回調函數 當您點擊鏈接時,請向下搜索以“如果repl是一個函數...”開頭的段落

import re
import random

def xdy(matchobj):
    x,y=map(int,matchobj.groups())
    s = 0
    for each in range(x):
        s += random.randint(1, y)
    return str(s)
s='1d6+2d6+2d6-72+4d100'
t=re.sub('(\d+)d(\d+)',xdy,s)
print(t)
# 5+10+8-72+197
print(eval(t))
# 148

Python不會讓你編寫全新的操作符,也不能用常規語言做括號。 你必須編寫一個遞歸下降解析器。 對於你的骰子滾動語言,這應該是非常簡單的。

或者,您可以使用現有的Python運算符並使用Pythons解析工具將文本轉換為AST。

看看PyParsing庫。 特別是, 示例頁面的樣本非常接近您想要的樣本

dice2.py

用於評估字符串的骰子滾動解析器和評估器,例如“4d20 + 5.5 + 4d6.takeHighest(3)”。

這使用了eval,這真的非常糟糕,但是你走了

>>> x = '1d6+2d6+2d6-72+4d100'
>>> eval(re.sub(r'(\d+)d(\d+)',r'sum((random.randint(1,x) for x in \1 * [\2]))', x))

一些快速說明:

這取代了4d6sum((random.randint(1,x) for x in 4 * [6]))

4 * [6]得到列表[6,6,6,6]

((random.randint(1,x) for x in [6,6,6,6]))是列表((random.randint(1,x) for x in [6,6,6,6]))的生成器等價物; 這個特殊的將返回1到6之間的四個隨機數。

在我的Supybot骰子插件中,我解析表達式

r'(?P<sign>[+-])((?P<dice>\d*)d(?P<sides>\d+)|(?P<mod>\d+))'

然后得到每個骰子和總修飾符的總數,滾動它們並獲得總結果(我想顯示每個骰子的總數)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM