Java - как проверить эту строку?

Существует ли на Java инструмент для выполнения такого рода задач ниже?

Я получил эту жестко напечатанную строку: {[1; 3] || [7; 9; 10-13]}

  • Фигурные скобки {} означают, что требуется

  • Квадратные скобки [] обозначают группу, которая требуется

  • Двойная труба || означает "ИЛИ"

Читая строку выше, мы получаем следующее:

  • Это обязательный, что НЕКОТОРЫЕ СТРОКИ имеет 1 И 3 ИЛИ ЖЕ 7 И 9 И 10, 11, 12 И 13

Если это правда, это пройдет. Если false, не пройдет.

Я пытаюсь сделать это в жестком коде, но чувствую, что есть более простой или ПРАВИЛЬНЫЙ ПУТЬ для этого типа проверки.

Какой тип контента мне нужно изучить, чтобы узнать об этом больше?

Я начал с этого кода, но считаю, что это неправильно:

//Gets the string
String requiredGroups = "{[1;3]||[7;9;10-13]}";

//Gets the groups that an Object belongs to
//It will return something like 5,7,9,10,11,12
List<Integer> groupsThatAnObjectIs = object.getListOfGroups();

//Validate if the Object is in the required groups
if ( DoTheObjectIsInRequiredGroups( groupsThatAnObjectIs, requiredGroups ) ) {
    //Do something
}

Я пытаюсь использовать этот итератор для получения требуемых значений из переменной requiredGroups

//Used for values like {[1;3]||[9;10;11-15]} and returns the required values    
public static void IterateRequiredValues(String values, List<String> requiredItems) {

    values = values.trim();

    if ( !values.equals("") && values.length() > 0 ) {

        values = values.replace("{", "");
        values = values.replace("}", "");

        String arrayRequiredItems[];

        if ( values.contains("||") ) {              
            arrayRequiredItems = values.split("||");
        }

        //NOTE: it's not done yet

    }

}
| называется трубкой (или «вертикальной полосой»)
jhamon 20.07.2018 15:36

В парсинге это называется регулярным выражением на любом языке, вот Ява

mallikarjun 20.07.2018 15:39

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

Zabuzard 20.07.2018 15:39

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

Antoine 20.07.2018 15:39

Можете ли вы показать некоторые примеры входных данных и желаемый результат? Какой длины струны вы хотите сопоставить? Должен ли он совпадать, только если все символы соответствуют этому шаблону? Или если есть? Так много вопросов, на которые вы легко сможете ответить, показав примеры.

Zabuzard 20.07.2018 15:42
1 AND 3 OR 7 AND 9 AND 10, 11, 13 - вы имеете в виду 10, 11, 12, 13?
khachik 20.07.2018 15:45

Что значит для String «иметь» 1 и 3? Чем это отличается от String, «имеющего» 13? Эти числа разделены символом?

VGR 20.07.2018 20:26
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
7
97
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Так что правила мне не совсем понятны. Например, вы сосредоточены только на || или у вас тоже есть &&? Если я посмотрю на ваш пример, я могу сделать вывод, что операторы && и неявны в ;.

Тем не менее, я сделал пример кода (без особого регулярного выражения), который проверяет ваши правила.

Для начала нужно начать с оператора ||. Поместите все различные операторы OR в блок String.

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

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

Если ваше правило состоит из диапазона, вы должны сначала полностью заполнить блок диапазона а затем сделайте то же самое с блоком диапазона, как и с обычным значением правила.

Полный пример кода ниже.

package nl.stackoverflow.www.so;

import java.util.ArrayList;
import java.util.List;

public class App 
{
    private String rules = "{[1;3] || [7;9;10-13] || [34;32]}";

    public static void main( String[] args )
    {
        new App();
    }

    public App() {

        String[] values = {"11 12", "10 11 12 13", "1 2 3", "1 3", "32 23", "23 32 53 34"}; 

        // Iterate over each value in String array
        for (String value : values) {
            if (isWithinRules(value)) {
                System.out.println("Success: " + value);
            }
        }   
    }

    private boolean isWithinRules(String inputValue) {
        boolean result = false;

        // || is a special char, so you need to escape it with \. and since \ is also a special char
        // You need to escape the \ with another \ so \\| is valid for one | (pipe)
        String[] orRules = rules.split("\\|\\|");

        // Iterate over each or rules
        for (String orRule : orRules) {

            // Remove [] and {} from rules
            orRule = orRule.replace("[", "");
            orRule = orRule.replace("]", "");
            orRule = orRule.replace("{", "");
            orRule = orRule.replace("}", "");
            orRule.trim();

            // Split all and rules of or rule
            String[] andRules = orRule.split(";");

            boolean andRulesApply = true;

            // Iterate over all and rules
            for (String andRule : andRules) {
                andRule = andRule.trim();

                // check if andRule is range
                if (andRule.contains("-")) {
                    String[] andRulesRange = andRule.split("-");
                    int beginRangeAndRule = Integer.parseInt(andRulesRange[0]);
                    int endRangeAndRule = Integer.parseInt(andRulesRange[1]);

                    List<String> andRangeRules = new ArrayList<String>();
                    // Add all values to another rule array
                    while (beginRangeAndRule < endRangeAndRule) {
                        andRangeRules.add(Integer.toString(beginRangeAndRule));
                        beginRangeAndRule++;
                    }

                    for (String andRangeRule : andRangeRules) {
                        // Check if andRule does not contain in String inputValue
                        if (!valueContainsRule(inputValue, andRangeRule)) {
                            andRulesApply = false;
                            break;
                        }
                    }

                } else {
                    // Check if andRule does not contain in String inputValue
                    if (!valueContainsRule(inputValue, andRule)) {
                        andRulesApply = false;
                        break;
                    }
                }
            }

            // If andRules apply, break and set bool to true because string contains all andRules
            if (andRulesApply) {
                result = true;
                break;
            }
        }

        return result;
    }

    private boolean valueContainsRule(String val, String rule) {
        boolean result = true;

        // Check if andRule does not contain in String inputValue
        if (!val.contains(rule)) {
            result = false;
        }

        return result;
    }
}

Ваш образ мышления очень помог мне решить эту проблему. Спасибо!

WitnessTruth 23.07.2018 14:24

Но у меня есть одно сомнение: как мне избежать двойной трубы "||" в {[1; 3] || [9; 10; 11-15]} через регулярное выражение? В шаблоне регулярного выражения, который я использую, он возвращает пустую строку между [1; 3] и [9; 10; 11-15], когда я использую сопоставитель

WitnessTruth 23.07.2018 14:31

Я думаю, вы можете сделать это, используя ^ и $, чтобы сопоставить начало и конец вашей строки

Igoranze 24.07.2018 18:23

Другие вопросы по теме