2016-02-25 113 views
1

可以使用哪些圖案分裂像這樣的字符串逗號模式:以這樣的方式拆分通過匹配

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

我可以匹配沒有用圓括號括起來的逗號嗎?

+0

yourString.split(「,」) –

+1

@ Jean-FrançoisSavard - 這也與所有逗號之間的逗號分開。 – DaoWen

+0

糟糕,讀得太快。 –

回答

0

有可能是這個殺手正則表達式,但什麼是更maintanable可能是:

  1. 臨時設置佔位符的括號
  2. 拆分所需的分離結果之間塊
  3. 用原始值替換佔位符

要使步驟1更一般化,您應該在分隔符的部分插入佔位符d不起作用。只要你能夠準確地確定這些部分是什麼,你就可以應用這個配方。

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. 
} 
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, ...的字符串)中,那麼這應該適用於類似於您的格式的輸入。

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爲ID

第1組CONCAT(a1.id,A2。 ID,a3.id)AS CNP

第2組是SUM(A3.nr)AS和

0

到底是太複雜了寫SQL解析器,所以我決定用ANTLR4。

我用這裏的例子,工作正常。 https://github.com/bkiers/sqlite-parser

但我不知道如何只提取查詢的某些部分(select,joins,order ...),我在網上找不到任何示例。有人能說明這是怎麼完成的嗎?

謝謝。