内部递归正则表达式java

时间:2013-03-08 15:39:13

标签: java regex

我有以下sql查询,我希望能够在一个正则表达式中进行分组:

CREATE INDEX blah_idx ON blah (id ASC)

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

我希望能够使用java正则表达式对这些进行分组,以便我得到:

blah_idx, blah, id, ASC

blah2_idx, blah2, foo, ASC, id, DEC

我可以使用CREATE INDEX (\\\w+) ON (\\\w+) \\((\w+) (\w+) \\)获得第一个,但我希望能够对第二个进行分组,但我无法定义\\((\w+) (\w+) \\)来重复匹配。

这甚至可能吗?

2 个答案:

答案 0 :(得分:1)

让我想起曾经问过的一个问题:

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

不幸的是,在包括Java在内的大多数Regexp语言中都不可能。

答案 1 :(得分:1)

为了便于阅读,我省略了一些括号。空格可以是\\s+*

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

允许使用嵌套组( ( ) ),并从左到右编号。有关检索,请参阅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));
        }
    }