1

1つの正規表現にグループ化できるようにしたい次の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+) \\)、2番目のものもグループ化できるようにしたいのですが、\\((\w+) (\w+) \\)繰り返し一致するように定義することができません。

これも可能ですか?

4

2 に答える 2

1

私がかつて尋ねた質問を思い出させます:

正規表現(再帰的?)を使用してネストされた関数の呼び出し(ブラケットのペア)を照合する方法

残念ながら、Javaを含むほとんどの正規表現言語では不可能です。

于 2013-03-08T15:42:52.717 に答える
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));
        }
    }
于 2013-03-08T15:46:48.827 に答える