用逗号模式匹配拆分

时间:2016-02-25 12:42:06

标签: java pattern-matching

我可以用什么模式来分割这样的字符串:

f.id AS id, CONCAT(a1.id, a2.id, a3.id) AS cnp, SUM(A3.nr) AS sum

以这样的方式,结果是这样的3个组的数组:

  1. f.id AS id
  2. CONCAT(a1.id, a2.id, a3.id) AS cnp
  3. SUM(A3.nr) AS sum
  4. 我可以匹配括号中没有括起的逗号吗?

5 个答案:

答案 0 :(得分:2)

该模式似乎始终采用... AS ...格式,您只需使用正则表达式即可:

Pattern p = Pattern.compile("(.*? as .*?)(,|$)", Pattern.CASE_INSENSITIVE );
String query = "f.id AS id, CONCAT(a1.id, a2.id, a3.id) AS cnp, SUM(A3.nr) AS sum";
Matcher m = p.matcher( query );
while ( m.find() ){
    System.out.println( m.group(1) );
}

IDEONE

只要您不希望任何相关的子查询嵌套在您的选择值(或其他边缘情况,例如包含' as error,' AS id, ...的字符串)中,那么这应该适用于与您的格式类似的输入。< / p>

答案 1 :(得分:0)

可能有一个杀手正则表达式,但更可能的是:

  1. 在括号中的块上临时设置占位符
  2. 将结果拆分为所需的分隔符
  3. 将占位符替换为原始值
  4. 为了使第1步更加通用,您应该在分隔符不起作用的部分插入占位符。只要您能够准确地确定这些部分是什么,您就可以应用此配方。

答案 2 :(得分:0)

使用@KevinEsche建议的实际SQL解析器可能是最强大的选择。

但是,如果你不需要解析所有SQL表达式,我只会使用普通的旧字符匹配:一次遍历字符串一个字符,计算嵌套在括号中的深度:

List<String> parts = new ArrayList<>();
int i = 0;
int depth = 0;
while (i < str.length()) {
  int start = i;
  while (i < str.length()) {
    char ch = str.charAt(i);
    if (ch == '(') {
      depth++;
    } else if (ch == ')') {
      depth--;
    } else if (ch == ',' && depth == 0) {
      break;
    }
    i++;
  }
  // Maybe check that depth == 0 here.
  parts.add(str.substring(start, i));
  i++;  // To skip the comma.
}

答案 3 :(得分:0)

感谢您的回答。我试图投票,但我还不能。 我用前瞻模式来解决问题:

String pattern = ",(?!([^(]*\\)))";
String str = "f.id AS id, CONCAT(a1.id, a2.id, a3.id) AS cnp, SUM(A3.nr) AS sum";
String strg [] = str.split(pattern);
for(int i=0;i<strg.length;i++) {
    System.err.println("Group "+i+" is "+strg[i]);
}

结果是:

组0是f.id AS id

第1组是CONCAT(a1.id,a2.id,a3.id)AS cnp

第2组是SUM(A3.nr)AS总和

答案 4 :(得分:0)

最后写一个SQL Parser太复杂了所以我决定使用ANTLR4。

我从这里使用了这个例子并且运行正常。 https://github.com/bkiers/sqlite-parser

但我不知道如何只提取查询的某些部分(选择,连接,顺序......),我在网上找不到任何例子。 someoane可以说明这是怎么做的吗?

谢谢。