tophersmith116
tophersmith116

Reputation: 442

internally recursive regular expression java

I have the following sql queries I'd like to be able to group in one regular expression:

CREATE INDEX blah_idx ON blah (id ASC)

CREATE INDEX blah2_idx ON blah2 (foo ASC, id DEC)

I'd like to be able to use a java regex to group these so that I get:

blah_idx, blah, id, ASC

blah2_idx, blah2, foo, ASC, id, DEC

I can get the first with CREATE INDEX (\\\w+) ON (\\\w+) \\((\w+) (\w+) \\) but I'd like to be able to also group the second but I can't see to define \\((\w+) (\w+) \\) to match repeatedly.

Is this even possible?

Upvotes: 1

Views: 3004

Answers (2)

Joop Eggen
Joop Eggen

Reputation: 109547

I left out some parentheses for readability. And spaces can be \\s+ or *.

"CREATE INDEX \\w+ ON \\w+ \\((\\w+ (ASC|DESC)(, \\w+ (ASC|DEC))*))\\)"
                              1     2        23       4       43 21   

Nested groups ( ( ) ) are allowed and are numbered from left to right. For retrieval see the javadoc.

    final String[] sqls = {
        "CREATE INDEX blah_idx ON blah (id ASC)",
        "CREATE INDEX blah2_idx ON blah2 (foo ASC, id DEC)",
        "CREATE INDEX blah2_idx ON blah2 (foo ASC, id DEC, name ASC)",
    };

    final Pattern createIndexPattern = Pattern.compile(
      "CREATE INDEX (\\w+) ON (\\w+) \\(((\\w+) (ASC|DESC)(, (\\w+) (ASC|DEC))*)\\)");
    for (String sql : sqls) {
        System.out.println("SQL: " + sql);
        Matcher m = createIndexPattern.matcher(sql);
        if (!m.matches()) {
            System.out.println("No match!");
        } else {
            System.out.println("Match!");
            int groupCount = m.groupCount();
            for (int groupI = 1; groupI <= groupCount; ++groupI) {
                System.out.printf("[%d] %s%n", groupI, m.group(groupI));
            }
            String[] fieldsWithOrdering = m.group(3).split(",\\s*");
            System.out.println(Arrays.toString(fieldsWithOrdering));
        }
    }

Upvotes: 1

Steve Chambers
Steve Chambers

Reputation: 39394

Reminds me of a question I once asked:

How to match nested function invocations (bracket pairs) using a regular expression (recursive?)

Not possible in most Regexp languages including Java unfortunately.

Upvotes: 1

Related Questions