Вопрос по parsing, java, string – Оценить строку как условие Java

20

Я должен получить набор значений столбца из D / B и проверить его как условие.

Например, у меня будут строки вроде"value > 2", "4 < value < 6" в столбце D / B. (значение - это то, которое сравнивается все время). У меня будет объявлено значение переменной в моем коде, и я должен оценить это условие.

int value = getValue();
if (value > 2)  //(the string retrieved from the D/B)
  doSomething();

Как я могу это сделать?? Любая помощь приветствуется. Благодарю.

Являются ли эти примеры единственными типами выражений? James Montagne
Да, неправильно прочитал ... удаленный пост dardo
это звучит довольно больно NimChimpsky
Я рекомендую найти лучший способ сделать это, иначе это должно быть сделано с помощью Reflection. Jivings
Насколько сложны струны? Вы можете проанализировать каждый из них, получить токены и использовать их для оценки выражений. ToastyMallows

Ваш Ответ

8   ответов
0

Вы должны попытаться разобрать строку внутри оператора if, выполнив что-то вроде

if(parseMyString(getValue()))
    doSomething();

В parseMyString можно определить, что нужно оценивать по условию. Если вы не знаете, как создать синтаксический анализатор, взгляните на:http://www.javapractices.com/topic/TopicAction.do?Id=87

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
1

Вы в основном оцениваете скриптовое выражение. В зависимости от того, что разрешено в этом выражении, вы можете получить что-то очень простое (регулярное выражение, идентифицирующее группы) или очень сложное (встроить движок javascript?).

Я предполагаю, что вы смотрите на простой случай, где выражение:   [border0] [оператор] & quot; значение & quot; [оператор] [border1]

Где одна, но не обе группы [border] [operator] могут быть опущены. (И если оба присутствуют, оператор должен быть одинаковым)

Я бы использовал регулярное выражение для этого с захватом групп.

Что-то вроде: (?: (\ D +) \ s * ([& lt; & gt;]) \ s *)? Value (?: \ S * ([& lt; & gt;]) \ s * (\ d +))?

А потом:   border1 = группа (1); оператор1 = группа (2); оператор2 = группа (3); border2 = группа (4)

Error: User Rate Limit Exceededstackoverflow.com/a/45730477/1833961
1

Это не будет тривиальным: вам нужен синтаксический анализатор для языка выражений, используемого в вашей базе данных. Если это какой-то стандартный, хорошо заданный язык, то вы можете найти его в Интернете, но если это что-то собственное, то вам, возможно, придется написать свой собственный (возможно, с использованием генератора синтаксического анализатора, такого как ANTLR.)

javax.script Пакет содержит несколько инструментов для интеграции внешних скриптовых движков, таких как интерпретатор Javascript. Альтернативная идея заключается в том, чтобы ввести механизм сценариев и передать выражения для этого.

Error: User Rate Limit Exceeded Venkateshwarrao Surabhi
32

Вот пример использования стандартной (Java 1.6+) библиотеки сценариев:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class Test {

    public static void main(String[] args) throws Exception {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("JavaScript");

        engine.eval("value = 10");
        Boolean greaterThan5 = (Boolean) engine.eval("value > 5");
        Boolean lessThan5 = (Boolean) engine.eval("value < 5");

        System.out.println("10 > 5? " + greaterThan5); // true
        System.out.println("10 < 5? " + lessThan5); // false
    }
}
Error: User Rate Limit Exceeded Venkateshwarrao Surabhi
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Venkateshwarrao Surabhi
Error: User Rate Limit ExceededengineError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Venkateshwarrao Surabhi
0

В последней версии Java (Java 7) разрешены операторы Switch Case для строк, если не так много возможных вариантов, вы можете просто сделать это или подобное:

int value = getValue();
switch(myString) {
  case "value > 2" : if (value > 2) {  doSomething();} break;
  case "4 < value < 6" : if (value > 4 && value < 6) {  doSomethingElse();} break;
  default : doDefault();
}
0

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

Использование MVEL имеет одно огромное преимущество перед использованием механизма сценариев в Java 1.6+ (в частности, с JavaScript): с MVEL вы можетеcompile скрипты для байт-кода, что делает их оценку намного более эффективной во время выполнения.

-4

Очень хороший способ сделать это помимо использования Java 7 - использовать enums. Объявите перечисление как показано ниже

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

enum MyEnum
{
    val1("value < 4"),val2("4<value<6");
    private String value;

    private MyEnum(String value)
    {
        this.value = value;
    }
}


public static void chooseStrategy(MyEnum enumVal)
{   
    int value = getValue();
    switch(enumVal)
    {
        case val1:
        if(value > 2){}
        break;
        case val2:
        if(4 < value && value < 6) {}
        break;
        default:
    }
}

public static void main(String[] args)
{
    String str = "4<value<6";
    chooseStrategy(MyEnum.valueOf(str));
}

Все, что вам нужно сделать, это передать вашу строку в метод enum.valueof, и он вернет соответствующее перечисление, которое помещается в блок case переключателя для выполнения условной операции. В приведенном выше коде вы можете передать любую строку вместо того, что передается в этом примере

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
0

Это не отвечает на ваш вопрос как таковой; он предлагает альтернативное решение, которое может повлиять на тот же результат.

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

Например, у вас может быть таблица, которая выглядит следующим образом.

CONDITION_ID | MINIMUM | MAXIMUM | IS_PRIME  |   ETC.
______________________________________________________
      1      |    2    |   NULL  |   NULL    |   ...
      2      |    4    |    6    |   NULL    |   ...

Эти записи строки, соответственно, соответствуют правиламvalue > 2 а также6 > value > 4.

Это дает ряд преимуществ по сравнению с подходом, который вы предоставляете.

  • Improved performance and cleanliness
  • Your conditions can be evaluated at the database level, and can be used to filter queries
  • You needn't worry about handling scenarios in which your pseudocode syntax is broken

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