可以使用哪些图案分裂像这样的字符串逗号模式:以这样的方式拆分通过匹配
f.id AS id, CONCAT(a1.id, a2.id, a3.id) AS cnp, SUM(A3.nr) AS sum
的结果是3个基团的一个这样的数组:
f.id AS id
CONCAT(a1.id, a2.id, a3.id) AS cnp
SUM(A3.nr) AS sum
我可以匹配没有用圆括号括起来的逗号吗?
可以使用哪些图案分裂像这样的字符串逗号模式:以这样的方式拆分通过匹配
f.id AS id, CONCAT(a1.id, a2.id, a3.id) AS cnp, SUM(A3.nr) AS sum
的结果是3个基团的一个这样的数组:
f.id AS id
CONCAT(a1.id, a2.id, a3.id) AS cnp
SUM(A3.nr) AS sum
我可以匹配没有用圆括号括起来的逗号吗?
有可能是这个杀手正则表达式,但什么是更maintanable可能是:
要使步骤1更一般化,您应该在分隔符的部分插入占位符d不起作用。只要你能够准确地确定这些部分是什么,你就可以应用这个配方。
使用@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.
}
模式似乎始终以格式... 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));
}
只要您不希望任何相关的子查询嵌套在您的选择值(或其他边缘情况,如包含' as error,' AS id, ...
的字符串)中,那么这应该适用于类似于您的格式的输入。
谢谢你的回答。我试图投票,但我还不能。 我提前用一下方式来解决这个问题:
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为ID
第1组CONCAT(a1.id,A2。 ID,a3.id)AS CNP
第2组是SUM(A3.nr)AS和
到底是太复杂了写SQL解析器,所以我决定用ANTLR4。
我用这里的例子,工作正常。 https://github.com/bkiers/sqlite-parser
但我不知道如何只提取查询的某些部分(select,joins,order ...),我在网上找不到任何示例。有人能说明这是怎么完成的吗?
谢谢。
yourString.split(“,”) –
@ Jean-FrançoisSavard - 这也与所有逗号之间的逗号分开。 – DaoWen
糟糕,读得太快。 –