如何在Python中计算自定义数学表达式

2024-06-17 10:15:15 发布

您现在位置: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

我使用正则表达式将所有的d替换为sum,然后使用eval,但是当处理两边的括号时,我的正则表达式崩溃了。有没有比实现自己的递归解析更快的方法呢?也许在eval中添加一个运算符?在

编辑:我似乎给出了一个不好的例子,因为上面的例子适用于我当前的版本。我要找的是一些评估方法,比如,(5+(6d6))d(7-2*(1d4))。
我所说的“崩溃”只是指我当前的正则表达式失败了。 我对我的失败太含糊其辞了,很抱歉给你带来了混乱。以下是我当前的代码:

^{pr2}$

为此,“1d6+4d100”工作正常,但“(1d6+4)d100”甚至“1d6+4d(100)”失败了。在


Tags: 方法in解析器for标准evalrange运算符
1条回答
网友
1楼 · 发布于 2024-06-17 10:15:15

Python不允许编写全新的运算符,也不能用常规语言来做括号。您必须编写一个递归下降解析器。这对你的掷骰子语言来说应该很简单。在

或者,您可以隐藏现有的Python操作符并使用Pythons解析工具将文本转换为AST。在

网友
2楼 · 发布于 2024-06-17 10:15:15

您可以将callback functionre.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
网友
3楼 · 发布于 2024-06-17 10:15:15

看看PyParsing库。{{a3}你想关闭的页面是什么:

dice2.py

A dice roll parser and evaluator for evaluating strings such as "4d20+5.5+4d6.takeHighest(3)".

相关问题 更多 >