可以使用哪些圖案分裂像這樣的字符串逗號模式:以這樣的方式拆分通過匹配
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
糟糕,讀得太快。 –