CrackSmoker9000
CrackSmoker9000

Reputation: 319

Python & regular expressions

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

Answers (3)

L3viathan
L3viathan

Reputation: 27273

Assuming you only have trusted data, you could just replace your math_func with eval and be done with it.

Upvotes: 1

Robin
Robin

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

Sufian Latif
Sufian Latif

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 characters

Upvotes: 1

Related Questions