@BLR_BOBR1K

Как проверить с помощью регулярного выражения математический пример на корректность?

Как проверить, что строка является синтаксически корректным математическим выражением. Математическое выражение может содержать следующие символы:числа, односимвольные переменные (a-­zA­-Z),знаки математических операций (+, ­, *, /), круглые скобки

Корректные примеры: 17*4+(x*54/(2+4))=y ; 2+2 ;18*41*с
Некорректные примеры: +45 ; 17+4* ;(34+1,45*3) ;(4+5))

вся проблема в том, что я не знаю как проверить на открытие и закрытие скобок в нужных местах
если без скобок, то получается как-то так:
(([a-z]|\d+)[\+\-\/\*]){1,}([a-z]|\d+)(=([a-z]|\d+))?

И надо сделать так, чтобы это работало на сайте www.regexr.com (вот такое условие)
  • Вопрос задан
  • 5560 просмотров
Пригласить эксперта
Ответы на вопрос 1
Lerg
@Lerg
Defold, Corona, Lua, GameDev
По-моему, в regex скобки учитывать очень сложно. Я бы вместо regex просто распарсил бы всё выражение. Или сначала выделил бы все выражения в скобках, а затем скормил бы всё это регулярному выражению.

Вот вам программка на питоне, которая выделяет все скобки и проверяет выражения в них. Написана на скорую руку, но работает. Загвоздка в том, что ваше регулярное выражение работает не совсем корректно, но вы уж сами поправьте. Мне уже лень.

Запускать можно в браузере: repl.it/3xv/1

Вам нужно лишь отредактировать выражение на 14 строке.

equations = """\
17*4+(x*54/(2+4))=y
2+2
18*41*с
+45
17+4*
(34+1,45*3)
(4+5)) 
x+z+(9/(5*(5669*(5+9)))
"""

import re

REGEX = re.compile(r"(([a-z]|\d+)[\+\-\/\*]){1,}([a-z]|\d+)(=([a-z]|\d+))?")

def matches(line, opendelim='(', closedelim=')'):
    stack = []
    for m in re.finditer(r'[{}{}]'.format(opendelim, closedelim), line):
        pos = m.start()
        if line[pos-1] == '\\':
            # skip escape sequence
            continue
        c = line[pos]
        if c == opendelim:
            stack.append(pos+1)
        elif c == closedelim:
            if len(stack) > 0:
                prevpos = stack.pop()
                yield (True, prevpos, pos, len(stack))
            else:
                # error
                yield (False, 0, 0, 0)
                pass
    if len(stack) > 0:
        for pos in stack:
            yield (False, 0, 0, 0)

def isPartCorrect(s):
    result = False
    if REGEX.match(s):
        result = True
    print("  check " + s + " -> " + str(result))
    return result
    
def isCorrect(s):
    result = True
    if s.find("(") >=0 or s.find(")") >= 0:
        for correct, openpos, closepos, level in matches(s):
            if correct:
                part = s[openpos:closepos]
                if part.find("(") == -1 and part.find(")") == -1:
                    if not isPartCorrect(part):
                        result = False
                        break
                part = s[openpos-1:closepos+1]
                replaced = s.replace(part, "p")
                if replaced.find("(") >=0 or replaced.find(")") >= 0:
                    if not isCorrect(replaced):
                        result = False
                        break
                else:
                    if not isPartCorrect(replaced):
                        result = False
                        break
            else:
                result = False
                break
    else:
        result = isPartCorrect(s)
    return result

for line in equations.splitlines():
    print(line)
    if isCorrect(line):
        print("    correct\n")
    else:
        print("    wrong\n")
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы