2015-10-14 185 views
0

我有一個包含創建查詢的字符串,我試圖根據逗號分割它。不幸的是,其中一些行在逗號中包含逗號。如何根據括號內的逗號分割字符串

例子:

dbo.Display_Test1.Column, 
CASE WHEN CHARINDEX(' To ', Test3) > 0 AND CHARINDEX('XVR', Test3) = 0 THEN LEFT(Test3, (CHARINDEX(' To ', Test3) - 12)) ELSE Test3 END AS Test3, 
dbo.Display_Test2.Column, 
ISNULL((CASE WHEN [2-Display-Test4].[Total Number] > 0 AND [1-Display-Test5].SumOfNumber = 0 THEN 0 ELSE (([2-Display-Test4].[Total Number] * 1000)/[1-Display-Test5].SumOfNumber) END), 0) AS Test6, 

我想根據不屬於(可能是多個)括號內的逗號分割我的字符串。作爲參考,我的例子應該分割的地方是換行符(雖然我的字符串沒有換行符)。

我已經嘗試了一些不同的解決方案,但沒有工作得很對:上線1,3

/(?:\(*[^()]*\)|[^,])+/g作品,和4,但第2行失敗,它打破了行成多個匹配。

/((?:[^,(]+|(\((?:[^()]+)|$1\)))+)/g在1,2和3行工作,但在第4行失敗。它也將行分成多個匹配。

我似乎不能使它工作。任何幫助表示讚賞。

+2

[這聽起來像你問的是錯誤的東西(http://meta.stackexchange.com/questions/66377/what -is-的-XY-問題/ 66378#66378)。 *爲什麼*你試圖在查詢結束之後拆分查詢(畢竟,在形成查詢之前,你想要的信息在沒有奇怪字符串拆分的情況下可用)?你想要提取什麼信息? –

+0

這是不可能的JavaScript正則表達式。 –

+0

請張貼明確的輸入/輸出樣本。即:「__i有這個_」和「__我需要這個_」。 –

回答

2

一種解決方案可能:(注:我們刪除了分離昏迷)

var str = "dbo.Display_Test1.Column, CASE WHEN CHARINDEX(' To ', Test3) > 0 AND CHARINDEX('XVR', Test3) = 0 THEN LEFT(Test3, (CHARINDEX(' To ', Test3) - 12)) ELSE Test3 END AS Test3, dbo.Display_Test2.Column, ISNULL((CASE WHEN [2-Display-Test4].[Total Number] > 0 AND [1-Display-Test5].SumOfNumber = 0 THEN 0 ELSE (([2-Display-Test4].[Total Number] * 1000)/[1-Display-Test5].SumOfNumber) END), 0) AS Test6,"; 
 
// if the string don't end by a coma , we add it. 
 
var strArr = str.replace(/,*\s*$/ , ',').split(''); 
 

 
var res; 
 
res = strArr.reduce(function(trans , charValue){ 
 

 
    if(charValue === '(') { 
 
    trans.deep++; 
 
    } 
 
    
 
    if(charValue === ')') { 
 
    trans.deep--; 
 
    } 
 
    
 
    if(trans.deep === 0){ 
 
    if(charValue===',') { 
 
     trans.arr.push(trans.str); 
 
     trans.str = ''; 
 
    }else{ 
 
     trans.str += charValue; 
 
    } 
 
    
 
    }else{ 
 
     trans.str += charValue; 
 
    } 
 
    return trans; 
 
    
 
}, { arr : [] , str : '' ,deep : 0}); 
 

 
document.write('<pre>' + JSON.stringify(res.arr , null , ' ') + '</pre>');


編輯

  • 作爲sugg注意到Thriggle在評論中我添加了字符串不會以昏迷結束的情況。
  • 更改變量名稱。
+0

好方法!然而,'看起來'布爾似乎沒有必要;所有重要的是深度衡量的'深'。這種方法也不能處理輸入字符串不以逗號結尾的情況(在這種情況下,它會留下最後一個元素)。 – Thriggle

+0

@Thriggle是的!看起來只是爲了我的測試目的,忘了/懶得刪除它。**(它已經遲到了)**關於最後的逗號,我不明白你的意思,如果字符串昏迷完成使用它,因爲它另外在開始之前添加它。我只是回答了你問的問題,我只是想引導你走一條路,我知道我無法爲你提供所有用例的解決方案。 :-) – Anonymous0day

0

當然,如果我們想用無限制的括號嵌套工作,那麼就不可能避免循環。對於一些有界的嵌套,我們可以編寫一個捕獲它的正則表達式。

長達1括號水平也可能是

/((?:[^(),]|\([^()]*\))+)/g 

長達2括號級(可能是你的情況下)

/((?:[^(),]|\((?:[^()]|\([^()]*\))*\))+)/g 

等等,與(?:[^()]|\([^()]*\))*

遞歸代 [^()]*
0

正則表達式不會讓你到達你想要的位置,並且仍然允許任意的複雜度。

一種方法是迭代字符串中的每個字符,跟蹤打開和關閉括號的時間,以及只有當開啓和關閉括號相互抵消時逗號分開(所以你知道你'不在括號內)。

function splitQuery(input){ 
    var arr = []; 
    var lastStart = 0; 
    var open = 0; 
    for(var i = 0, len = input.length; i < len; i++){ 
    var curr = input[i]; 
    if(curr === "("){open += 1;} 
    else if(curr === ")"){ open = open < 1 ? 0 :open -=1;} 
    else if(curr === ","){ 
     if(open === 0){ 
     arr.push(input.substring(lastStart,i)); 
     lastStart = i+1; 
     } 
    }else if(i+1 === len){ 
     arr.push(input.substring(lastStart,i+1)); 
    } 
    } 
    return arr; 
} 

請注意,在處理特別大的字符串時,此方法可能會很昂貴(從性能角度來看)。

這裏有一個工作示例:

var query = "dbo.Display_Test1.Column, CASE WHEN CHARINDEX(' To ', Test3) > 0 AND CHARINDEX('XVR', Test3) = 0 THEN LEFT(Test3, (CHARINDEX(' To ', Test3) - 12)) ELSE Test3 END AS Test3, dbo.Display_Test2.Column, ISNULL((CASE WHEN [2-Display-Test4].[Total Number] > 0 AND [1-Display-Test5].SumOfNumber = 0 THEN 0 ELSE (([2-Display-Test4].[Total Number] * 1000)/[1-Display-Test5].SumOfNumber) END), 0) AS Test6,"; 
 

 
var split = splitQuery(query); 
 
var output = document.getElementById("output") 
 
for(var el in split){ 
 
    output.insertAdjacentHTML("beforeend",el + ": "+ split[el]+"<hr/>"); 
 
} 
 

 
function splitQuery(input){ 
 
    var arr = []; 
 
    var lastStart = 0; 
 
    var open = 0; 
 
    for(var i = 0, len = input.length; i < len; i++){ 
 
    var curr = input[i]; 
 
    if(curr === "("){open += 1;} 
 
    else if(curr === ")"){ open = open < 1 ? 0 :open -=1;} 
 
    else if(curr === ","){ 
 
     if(open === 0){ 
 
     arr.push(input.substring(lastStart,i)); 
 
     lastStart = i+1; 
 
     } 
 
    }else if(i+1 === len){ 
 
     arr.push(input.substring(lastStart,i+1)); 
 
    } 
 
    } 
 
    return arr; 
 
}
<div id="output"></div>

相關問題