regex that matches simple arithmetic expressions

Question:

i have a solution, but the only problem is that for example "7=7=7" is matched and that should not be the case.

^[+-]?d+([/*+-]d+)*([/*+-]*=(?:[+-]?d+([/*+-]d+)*)+)*$

see below of what is matched and not

these are matched and that is correct

456+5
0
0+0
5=0
1589+232
55+2
5+55
545454545
-12*53+1-2/5
+1+2+3=-5*2/3
000=0
18=+17/25
0-0
0*0
0/0
1/1
5/5
6*6
55/55
1/22
+55
5+5+5+5+5+5+5+5+5+5+5+5+5+5+5+5+5+5*5*5*5/5/5/5*5*5*5=5*5*5*5*5*5*5*5*5*5*5*5*5*5/5+5/5-6/5555/6
0*0*0*0*0*0*0+0=00000000*0*0
003+3*2

these shouldnt be matched which all of them except "7=7=7" does.

0=
5654*45=
*23
55++55
55+
7=7=7
18/-35
5*x
3.14159265358

how can i fix that the equal sign can only be there once, while also having a must that if a equal sign is there then there has to be a number after that

the answer must a regex

Asked By: alex

||

Answers:

You could replace the final * with ?: that way it can only occur once at the most:

^[+-]?d+([/*+-]d+)*([/*+-]*=(?:[+-]?d+([/*+-]d+)*)+)?$

Be aware that your regex also allows this:

1+1++++++++=1

That doesn’t seem right. I’m not sure why you have that [/*+-]* sitting before =.

You could avoid some repetition by using a negative look ahead assertion:

^(?!.*=.*=)[+-]?d+(([/*+-]|=[+-]?)d+)*$
Answered By: trincot

You can match the follow regular expression.

^(?:[+-]?(?:d+[+/*-])*d+=)?[+-]?(?:d+[+/*-])*d+$

This does not match any string that contains more than one equals sign.


Demo

^           match the beginning of the string
(?:         begin a non-capture group (A)
  [+-]?     optionally match one of the two characters in the character class
  (?:       begin a non-capture group (B)
    d+     match one or more digits
    [+/*-]  match one of the four characters in the character class
  )         end non-capture group B
  *         execute non-capture group B zero or more times
  d+       match one or more digits
  =         match '='
)           end non-capture group A
?           optionally match non-capture group A
[+-]?       optionally match one of the two characters in the character class
(?:         begin a non-capture group (C)
  d+       match one or more digits
  [+/*-]    match one of the four characters in the character class
)           end non-capture group C
*           execute non-capture group C zero or more times
d+         match one or more digits
$           match end of the string

If you were to use Python’s alternative regex engine (import regex) you could make use of the fact that it supports subroutines (a.k.a "subexpressions"):

^(?:([+-]?(?:d+[+/*-])*d+)=)?(?1)$

(?1) causes itself to be replaced by the directives that match and save to capture group 1 (([+-]?(?:d+[+/*-])*d+)). Not only does that reduce the size of the expression, it reduces the chance of errors being introduced.

Demo

Answered By: Cary Swoveland
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.