You can use this link to evaluate my regex.
I'm trying to validate an infix input whether it's in the right form or not.
This is my test cases:
1 --> (12 4)^3-((13 2)-(4*5)) //should be correct
2 --> )3 7( //should be wrong
3 --> 2 //should be wrong
4 --> 2 4- //should be wrong
5 --> (19*7)) //should be wrong
6 --> 2 8 //should be correct
So now you might know what's on my mind . I red many websites and questions and concluded that I should use recursive regex.
So I tried to recognize the pattern and I came with this(incorrect version):
(^(\(?[0-9] (\ \-\*\/\^)[0-9]*\))|^([0-9] (\ \-\*\/\^)[0-9] (?1)*))(?1)*$
And I implemented that in python using regex (not re) library:
import regex
regex.search(r"(^(\(?[0-9] (\ \-\*\/\^)[0-9]*\))|^([0-9] (\ \-\*\/\^)[0-9] (?1)*))(?1)*$","(12 4)^3-((13 2)-(4*5))") is not None
The expected output should be True but my output is False .
I know my pattern is incorrect and need your help.If you know better pattern that would be nice!Thanks.
CodePudding user response:
I ... concluded that I should use recursive regex.
This is indeed possible with a recursive regex, which is what the regex
library supports.
One of the mistakes in your attempt is that (\ \-\*\/\^)
does not represent a choice of operator, but requires all of them to appear in that sequence. You need [ */^-]
syntax.
I would suggest this regular expression:
result = regex.match(r"^(([ -]*\d |\((?1)\))([ ^*/-](?2))*)$", s)
This assumes that your input has no spaces, and the numeric literals are (signed) integers.
Explanation:
[ -]*
: any sequence of these two characters, which serve as unary operators.\d
: any non-empty sequence of digits, representing an unsigned integer(?1)
: recursion. This will use the whole regular expression -- except for the^
and$
anchors! -- in a recursive way. With the surrounding, literal parentheses, this allows for expression nesting.[ ^*/-]
: any binary operator (extend with more operators as needed)(?2)
: to match the second operand of a binary operator, re-using the same pattern as was used to match the first operand.