Регулярное выражение для поиска соответствия некорректной записи С++

Реализую строковый калькулятор, где у меня есть этап, на котором я перед вычислением выражения делаю проверку на валидность выражения.

Для поиска использую язык С++, PCRE

bool Calculation::expression_validate(QString& infix) {
  QVector<QRegularExpression> regex{
      QRegularExpression(".(?<![+\\-*\\/^(.]|mod|\\d)(\\d)"),
      QRegularExpression("(?<![)x]|\\d)([\\*\\/^]|mod)"),
      QRegularExpression("(?<![)x]|\\d)([+\\-\\*\\/^]|mod)([+-])"),
      QRegularExpression("(?<![())x+\\-\\*\\/^]|\\d|mod)([+-])"),
      QRegularExpression(".(?<![+\\-*\\/^(a]|mod)(a?(cos|sin|tan)|sqrt|ln)"),
      QRegularExpression(".(?<![+\\-*\\/^(sntgd])[(]"),
      QRegularExpression("(?<!\\d|[)]|x)[)]"),
      QRegularExpression("\\d*?[.]\\d*?[.]\\d*?"),
      QRegularExpression(".(?<!\\d|[\\)x])$")};
  bool check = true;
  for (auto it : regex) {
    if (infix.contains(it)) {
      check = false;
      break;
    }
  }
  return check;
}

Калькулятор работает с простыми операциями как [+-*/^]|mod, так и тригонометрическими функциями cos|sin|tan|acos|asin|atan|ln|log + sqrt

Обработка всех сочетаний использования операторов, функций и цифр, а также x

cos(5+1.34^6--ln(2.71))
(((((((-5))))))))
-x^2^(1/cos(1))

Вопрос в следующем: каким образом переписать регулярные выражения на так называемый правильный вид, чтобы избавится от костылей как в следующем выражении?

                 ->|.            ->|a
QRegularExpression(".(?<![+\\-*\\/^(a]|mod)(a?(cos|sin|tan)|sqrt|ln)")

(выражение)

В данном выражении обрабатываются функции, перед которыми не должно быть след.символов [+\\-*\\/^(a]:

  1. Первая проблема в том, что запись без . and a в выражении 5+acos(1) найдёт сравнение cos, перед которым a, которое не входит в список значений на сравнение.
  2. Обработка в начале строки данного выражения находит null, для обхода этого стоит костыль на любой символ для избежания проверки в начале строки.

Также завершающим этапом проверки является проверка на валидность по скобочкам, в какой они последовательности, и их количество, на просторах интернета нашёл рег.выражение:

^[^()\n]*+(\((?>[^()\n]|(?1))*+\)[^()\n]*+)++$

Вопрос в следующем: каким образом переписать его, чтобы та находила противоположные значения, отличные от верных?


Ответы (0 шт):