-1

I'd like to process some input queries in 3 possible ways:

query: select * from People 
query: select * from People exclude addresses
query: select * from People include department

I have two regex1 query[:\/]?(.*)((exclude|include)(.*))? and regex2 query[:\/]?(.*)((exclude|include)(.*))(no question mark at the end)

Regex1 MATCHES all three scenarios above, but I lose the capturing groups (2) like: exclude addresses, include departments and I don't want to user extra substring operations to extract exclude addresses, include departments from the original string, as this can be achieved from capturing groups.

Regex2 MATCHES only the queries that contain Exclude/Include options, i.e. it doesn't MATCH the query: select * from People It catures the query - in the 1st capturing group, and the exclusions/inclusions - in the second capturing group

How to update the RegEx that I have MATCH on all 3 cases with optional matching groups? i.e. groupCount() == 3, I have inclusions/exclusions, and groupCount() == 2 indicates I have a simple query only. Thank you.

Got a solution from ChatGPT

import java.util.regex.*;
public class QueryParser {
public static void main(String[] args) {
    String[] tests = {
        "query:select * from People",
        "query: select * from People exclude addresses",
        "query/select * from People include department",
        "query select * from People",
        "non matchning query"
    };

    String regex = "^query[:\\/]?\\s*(.*?)(?:\\s+(exclude|include)\\s+(.*))?$";
    Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

    for (String test : tests) {
        Matcher matcher = pattern.matcher(test);
        if (matcher.matches()) {
            System.out.println("Full match: " + matcher.group(0));
            System.out.println("Main query: " + matcher.group(1));
            System.out.println("Exclude/include keyword: " + matcher.group(2));
            System.out.println("Exclude/include parameters: " + matcher.group(3));
            System.out.println("---");
        } else {
            System.out.println("No match for: " + test);
        }
    }
}

with better than desired outputs

4
  • 6
    I’m not sure I understand your question, but I suspect changing the first (.*) to (.*?) will fix the problem, so it doesn’t “consume” the remainder of the line. Commented Oct 22 at 13:27
  • 1
    The question is unclear. Please edit to add example inputs, actual outputs and expected outputs of the scenarios that are failing. Commented Oct 22 at 14:18
  • 3
    btw. I suspect the group count will always be same (unless for different regular expressions) - javadoc: "Returns the number of capturing groups in this matcher's pattern" (in the pattern, not the number of actually matched groups) Commented Oct 22 at 18:17
  • Yes the group count is the same. For query: select * from People the exclusion/inclusion groups will be null. You just check if the 3rd captured group did or did not capture something - yet it is still a match Commented Oct 24 at 2:45

2 Answers 2

1

I think this version might help you to achieve what you want. However, instead of having only 2 groups when the exclude/include section is absent, you would still have three groups, where the third one is an empty string. So, instead of checking whether there are 2 groups or 3, you can check if the third group is an empty string.

(?i)query:\s*(.*?)\s*(exclude.*|include.*|)$
  • (?i) allows case-insensitive match.

  • query:\s* prefix before each query.

  • (.*?) query part captured in group 1.

  • \s* zero or more white spaces between the query and include or exclude.

  • (exclude.*|include.*|)$ group 2 capturing the ending part, which can be an exclude, an include, or an empty string.

Here is a link to test the regex:

https://regex101.com/r/kBGx08/1

Sign up to request clarification or add additional context in comments.

Comments

-1

Changing the regex to query[:\/]?(.*)(((exclude|include)(.*))?) means it should return groups(2) as either empty or containing the whole include/exclude string. If groups(2) is not empty then group(3) should contain include or exclude and group(4) the text to end of string.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.