Reputation: 319
Hi i'm making a program that will take a command such as !math(5+5)
from skype and return the result, i'm having trouble getting the regex expression right, I have been reading the docs and I just can't get it right.
I am trying to support all operators, so , * /, +, -, %, and **. the trouble comes when I try to use **, either I use one regex and lose the option for exponents or have the exponent only option.
Here's my expression:
expr = re.search(r'((\d+)(\s*.?|.*\**)(\d+))', 'math(500**1000)')
And then i'm parsing it using groups,
build_expr = {
'number1': int(expr.group(2)),
'operator': expr.group(3),
'number2': int(expr.group(4))
}
results for giving the reseach module the argument with exponents:
>>> expr.group()
'500**1000'
>>> expr.group(1)
'500**1000'
>>> expr.group(2)
'500'
>>> expr.group(3)
'**100'
And it works just fine and dandy with 1 character strings, such as math(500+1000)
>>> expr.group(1)
'500+1000'
>>> expr.group(2)
'500'
>>> expr.group(3)
'+'
>>> expr.group(4)
'1000'
Here's the entire function
def math_func(expr_arg):
expr = re.search(r'((\d+)(\s*.?|.*\**)(\d+))', expr_arg)
#parse_expr = ' '.join(expr.group()).split()
build_expr = {
'number1': int(expr.group(2)),
'operator': expr.group(3),
'number2': int(expr.group(4))
}
if build_expr['operator'] == '+':
operation = build_expr['number1'] + build_expr['number2']
return str(operation)
elif build_expr['operator'] == '-':
operation = build_expr['number1'] - build_expr['number2']
return str(operation)
elif build_expr['operator'] == '/':
operation = build_expr['number1'] / build_expr['number2']
return str(operation)
elif build_expr['operator'] == '%':
operation = build_expr['number1'] % build_expr['number2']
return str(operation)
elif build_expr['operator'] == '*':
operation = build_expr['number1'] * build_expr['number2']
return str(operation)
elif build_expr['operator'] == '**':
operation = build_expr['number1'] ** build_expr['number2']
return str(operation)
else:
return 'Invalid operator'
return 'shes all good son'
f = math_func('math(500+1000)')
Message.Chat.SendMessage('>> ' + f)
Upvotes: 2
Views: 118
Reputation: 27273
Assuming you only have trusted data, you could just replace your math_func
with eval
and be done with it.
Upvotes: 1
Reputation: 9644
How about just using:
(\d+)\s*(\*\*|[+/%*-])\s*(\d+)
[+/%*-]
means "one character, one from the list inside brackets".
No need to wrap everything inside a capturing group, the whole match is already stored in group(0)
.
I'm not sure how you got to .*\**
so I can't tell you what's your mistake is here, but the new regex should do the job.
Upvotes: 1
Reputation: 13356
It can be matched using:
(\d+)\s*([-+*/%]+)\s*(\d+)
Breakdown:
(\d+)
will match one or more digits\s*
will match the whitespaces, if there's any([-+*/%]+)
will match one or more operator charactersUpvotes: 1