How to evaluate a custom math expression in Python
Question: I'm writing a custom dice rolling parser (snicker if you must) in python.
Basically, I want to use standard math evaluation but add the 'd' operator:

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

So that, for example, 1d6+2d6+2d6-72+4d100 = (5)+(1+1)+(6+2)-72+(5+39+38+59) =
84

I was using regex to replace all 'd's with the sum and then using eval, but my
regex fell apart when dealing with parentheses on either side. Is there a
faster way to go about this than implementing my own recursive parsing?
Perhaps adding an operator to eval?

Edit: I seem to have given a bad example, as the above example works with my
current version. What I'm looking for is some way to evaluate, say,
(5+(6d6))d(7-2*(1d4)).  
By "fell apart", I just meant that my current regex expression failed. I have
been too vague about my failure, sorry for the confusion. Here's my current
code:

    
    
    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())
    

for this, "1d6+4d100" works just fine, but "(1d6+4)d100" or even "1d6+4d(100)"
fails.


Answer: You could use a [callback
function](http://docs.python.org/library/re.html#re.sub) with `re.sub`. When
you follow the link, search down to the paragraph beginning with "If repl is a
function..."

    
    
    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
    

