0

Do it exists a tool in Java to do this type of task below?

I got this hard typed String: {[1;3] || [7;9;10-13]}

  • The curly brackets {} means that is required

  • The square brackets [] means a group that is required

  • The double pipe || means a "OR"

Reading the string above, we get this:

  • It's required that SOME STRING have 1 AND 3 OR 7 AND 9 AND 10, 11, 12 AND 13

If true, it will pass. If false, will not pass.

I'm trying to do this in hard coding, but I'm felling that there is an easier or a RIGHT WAY to this type of validation.

Which type of content I must study to learn more about this?

I started with this code, but I'm felling that is not right:

//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
}

I'm trying to use this iterator to get the required values from the requiredGroups variable

//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

    }

}
7
  • 1
    |is called a pipe (or "vertical bar") Commented Jul 20, 2018 at 13:36
  • Th parsing it is called regular expression in any language, here is the java Commented Jul 20, 2018 at 13:39
  • Can you show us your attempt? It may be easier to understand the requirements by looking at the code. Commented Jul 20, 2018 at 13:39
  • 1
    Can you show some example inputs and the desired output? How long are the strings you want to match? Should it match only if all character match that pattern? Or if any? So many questions that you can easily answer by showing examples. Commented Jul 20, 2018 at 13:42
  • 1
    1 AND 3 OR 7 AND 9 AND 10, 11, 13 - you mean 10, 11, 12, 13? Commented Jul 20, 2018 at 13:45

1 Answer 1

2

So the rules are not really clear to me. For example, are you only focussing on || or do you also have &&? If I look at your example, I can derive from it that the && and operators are implicit in the ;.

None the less, I have made a code example (without much regex) that checks your rules.

First you need to begin with the || operator. Put all the different OR statements into a String block.

Next you will need to check each element in the String block and check if the input value contains all block values.

If so then it must be true that your input string contains all the rules set by you.

If your rule consists of a range, you must first fully fill the range block and then do the same with the range block as you would with the normal rule value.

Complete code example below.

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;
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Your way of thinking helped me a lot to solve this problem that I had. Thank you!
But I have one doubt: How can I escape the double pipe "||" in the {[1;3]||[9;10;11-15]} via regex? In the regex pattern that I'm using it's returning an empty string between [1;3] and [9;10;11-15] when I use the matcher
I think you can do it by using ^ and $ to match the start and end of your string

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.