2015-10-14 121 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>

相关问题