1

I'm trying to check if a string is a valid math expression. Allowed operations are +,-,*,/ and ^. I tried this and don't know why it doesn't work:

a = raw_input("Unesite izraz")
if len( re.findall(r'(\d+(?:.\d+)?(?: [\+\-\/\*\^]\d+(?:.\d+) )* )', a ) ) != 0:

But this regex expression returns [] for valid expressions. Why? Thanks!

1
  • Not really an answer, but when you match a number \d+(?:.\d+)?, the dot should be escaped as \., since otherwise '1a3' and '9(10' would be considered valid numbers. Commented Dec 12, 2015 at 21:01

3 Answers 3

2

A validator for a simple symbol math expression could be something like this.
This would be a 1 time match of the entire string.

^\s*[+-]?\s*(?:\d+(?:\.\d*)?|\.\d+)(?:\s*[-+/*^]\s*\s*[+-]?\s*(?:\d+(?:\.\d*)?|\.\d+))*\s*$

Formatted:

 ^                             # BOS
 \s* [+-]? \s*                 # whitespace (opt), sign (opt), whitespace (opt)
 (?:                           # Integer or decimal
      \d+ 
      (?: \. \d* )?
   |  \. \d+ 
 )
 (?:                           # Cluster group
      \s* [-+/*^] \s*               # whitespace (opt), operation symbol (req'd), whitespace (opt)
      \s* [+-]? \s*                 # whitespace (opt), sign (opt), whitespace (opt)
      (?:                           # Integer or decimal
           \d+ 
           (?: \. \d* )?
        |  \. \d+ 
      )
 )*                            # End cluster, do 0 to many times
 \s*                           # optional whitespace
 $                             # EOS
Sign up to request clarification or add additional context in comments.

2 Comments

This works, thanks, but shouldn't we use \ in front of +,- etc.
The + is inside a character class where its not a quantifier .. no need to escape it. Likewise the * and^.
1

You have spaces in the wrong places.

# yours / fixed
r'(\d+(?:.\d+)?(?: [\+\-\/\*\^]\d+(?:.\d+) )* )'
r'(\d+(?:.\d+)?(?: [\+\-\/\*\^] \d+(?:.\d+) )*)'

You can try them at pythex.org

Comments

1

You can simplify your regexp.

There is the operator "except": [^abc] Thus, it will take whatever is not the characters "a", "b" or "c".

import re

e1 = '1 + 2' # correct
e2 = '1 + 3 * 3 / 6 ^ 2' # correct
e3 = '1 + 3 x 3' # wrong

el = [e1, e2, e3]
regexp = re.compile(r'[^+\-*\/^0-9\s]')
for i in el:
    if len(regexp.findall(i)):
        print(i, 'wrong')
    else:
        print(i, 'correct')

You can use this site to learn and test yours regexp: https://regex101.com/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.