Проверить, является ли строка математическим выражением или нет?

Я пытаюсь написать метод на Java, который принимает строку в качестве аргумента. Теперь эта строка может быть математическим выражением или просто обычной строкой. Я должен оценивать его, только если это математическое выражение, и оставлять его в покое, если это не так. Я оцениваю математическое выражение, используя движок java-скриптов, следующим образом:

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "1+2*10";
System.out.println(engine.eval(foo));

Но проблема в том, что если я передаю строку, которая не является математическим выражением, это вызывает исключение. Мне не нужны исключения в моем коде. Я пытаюсь достичь примерно следующего:

if(isExpression(foo))
{
engine.eval(foo);
}

Таким образом, я проверяю, является ли это математическим выражением, прежде чем оценивать его. Есть ли простая реализация метода isExpression (foo)? Может быть, используется какое-то регулярное выражение? Пожалуйста, дайте мне знать, если они есть. Спасибо


person Aswin Parthasarathy    schedule 22.06.2012    source источник
comment
Воткнуть это в попытку / уловить?   -  person Jodaka    schedule 22.06.2012
comment
Почему бы вам просто не поймать исключение и не обработать его?   -  person opyate    schedule 22.06.2012
comment
Найдите лексер и анализатор javascript с открытым исходным кодом, при необходимости преобразуйте его в Java, затем выполните лексирование и синтаксический анализ строки и посмотрите, что произойдет. В качестве альтернативы найдите грамматику javascript для выражений, загрузите их в ANTLR или Bison, а затем используйте это, чтобы определить, действительно ли выражение. Или просто поймайте исключение.   -  person dlev    schedule 22.06.2012
comment
да, я мог бы это сделать, но это не ... ну ... хорошая привычка кодировать, не так ли?   -  person Aswin Parthasarathy    schedule 22.06.2012
comment
Плохая привычка кодирования - не обрабатывать исключения, и еще хуже, когда вы знаете где, а просто позволяете исключению распространяться по всему коду.   -  person Luiggi Mendoza    schedule 22.06.2012
comment
В: Да, я мог бы это сделать, но это не ... ну ... хорошая привычка кодировать, не так ли? Использование хорошей библиотеки - плохая привычка кодить? Лучше велосипед изобретать? Отлавливать исключения - это нехорошие навыки программирования?!? Где вы слышали это?!?   -  person paulsm4    schedule 22.06.2012
comment
Вы могли бы использовать регулярное выражение, чтобы поймать очевидное нематематическое значение (один простой случай, что-либо с буквой), но было бы трудно отличить что-то вроде 1 + 2 * 56 от 1 + * 256 (на самом деле, вы, вероятно, могли бы это сделать, но рассмотрите 1 * + 256, что технически законно).   -  person user949300    schedule 22.06.2012
comment
@ paulsm4, вы могли бы сказать это лучше, не так грубо. использование чего-то вроде if (isExpression (foo)) лучше и чище, чем обработка исключения и выполнение действий на его основе, и я спрашивал только об этом.   -  person Aswin Parthasarathy    schedule 22.06.2012


Ответы (5)


Для действительно сложных операций, подобных этой, усилия по проверке правильности формулы почти равны усилиям по фактической оценке.

Я рекомендую вам просто попытаться оценить и, в случае неудачи, выбросить исключение для домена, например CannotEvaluateFormulaException, и поймать его.

person user949300    schedule 22.06.2012

В: Есть ли встроенная функция Java для оценки того, что 1+2*10 является выражением, а AB@C#! - нет?

A: No.

Использование регулярного выражения может приблизить вас, но кому-то необходимо проанализировать и попытаться оценить строку, прежде чем вы сможете определить, действительно ли это арифметическое выражение.

ПРЕДПОЛОЖЕНИЕ:

Вызовите свой движок и выловите любые исключения.

PS:

Вы должны делать это в любом случае, независимо от «допустимое выражение / не выражение». Правильный?

person paulsm4    schedule 22.06.2012

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

Не стыдно выбрасывать исключения, пока вы их ловите, они для этого и созданы! Конечно, есть некоторые накладные расходы при генерировании и перехвате исключения, но вы должны оценить это по сравнению с вашей начальной предварительной проверкой, которая будет выполняться для всех выражений, правильных или нет.

Тем не менее, взгляните на шаблон интерпретатора, чтобы оценить свое выражение, если ни у кого нет лучшего готовое предложение, особенно если у вас есть простые обычные математические выражения без специальных расширений / логики / чего угодно (посмотрите, например, решение @ user1264811!)

person Miquel    schedule 22.06.2012

вам нужно попробовать и поймать.

см. обработку исключений

person Frank Visaggio    schedule 22.06.2012

Вы можете проверить это, если хотите создать какой-нибудь калькулятор: users.cis.fiu.edu/~weiss/dsj2/code/Evaluator.java.

person helsont    schedule 22.06.2012