2

I'm attempting to write a regex to prevent certain user input in mathematical expressions. (e.g. '1+1' would be valid whereas'1++1' should be invalidated) Acceptable characters include *digits 0-9* (\d works in lieu of 0-9), + - # / ( ) and white-spaces.

I've attempted to put together a regex but I cant find anything in python regular expression syntax that would validate (or consequently invalidate certain characters when typed together. (( is ok ++, --, +-, */, are not

I hope there is a simple way to do this, but I anticipate if there isn't, I will have to write regex's for every possible combination of characters I don't want to allow together.

I've tried:

re.compile(r"[\d\s*/()+-]") 
re.compile(r"[\d]\[\s]\[*]\[/]\[(]\[)]\[+]\[-]")

I expect to be able to invalidate the expression if someone were to type "1++1"

Edit: Someone suggested the below link is similar to my question...it is not :)

Validate mathematical expressions using regular expression?

KalmaH
  • 29
  • 3
  • Possible duplicate of [Validate mathematical expressions using regular expression?](https://stackoverflow.com/questions/11009320/validate-mathematical-expressions-using-regular-expression) – vs97 Aug 13 '19 at 12:11

3 Answers3

0

Probably the way to go is by inverting your logic: abort if the regex detects any invalid combination - those are much less compared to the amount of valid combinations.

So e.g.: re.compile(r"++")

Also, is it possible at all to enumerate all valid terms? If the length of the term is not limit, it is impossible to enumerate all vaild terms

Martin
  • 184
  • 10
  • For the purpose of what I've been asked to do in an assignment, it may be easier for me to write a case to handle each request. (What I'm doing is modifying a python lambda function through an amazon API gateway. A "user" will attempt to POST to my API (by way of curl or Postman) in json payloads (e.g. {"user": "some name", "calc": "1++1"} My code should validate that username is only alphanumeric, and that only specific characters of mathematic expressions are validated. If both are satisfied, it is safe to run and return the output in the response. If not, they will get a "Forbidden" – KalmaH Aug 13 '19 at 12:25
0

Perhaps one option might be to check the string for the unwanted combinations:

[0-9]\s*(?:[+-][+-]|\*/)\s*[0-9]

Regex demo | Python demo

For example

pattern = r"[0-9]\s*(?:[+-][+-]|\*/)\s*[0-9]"
strings = [
    'This is test 1 -- 1',
    'This is test 2',
    'This is test 3+1',
    'This is test 4 */4'
    ]

for s in strings:
    res = re.search(pattern, s)
    if not res:
        print("Valid: " + s)

Result

Valid: This is test 2
Valid: This is test 3+1
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
0

Below is a snippet from my code. This is hardly the solution I was originally looking for but it does accomplish what I was trying to do. When a user curls to an api endpoint 1++1, it will return "Forbidden" based on the below regex for "math2 =...." Alternatively, it will return "OK" if a user curls 1+1. I hope I am understanding how Stack Overflow works and have formatted this properly...

# returns True if a valid expression, False if not.
def validate_expression(calc):
    math = re.compile(r"^[\d\s*/()+-]+$")
    math2 = re.compile(r"^[\d++\d]+$")
    print('2' " " 'validate_expression')
    if math.search(calc) is not None and math2.search(calc) is None:
        return True
    else:
        return False
KalmaH
  • 29
  • 3