如何根据括号内的逗号分割字符串
我有一个包含创建查询的字符串,我试图根据逗号分割它。不幸的是,其中一些行在逗号中包含逗号。如何根据括号内的逗号分割字符串
例子:
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行失败。它也将行分成多个匹配。
我似乎不能使它工作。任何帮助表示赞赏。
一种解决方案可能:(注:我们删除了分离昏迷)
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在评论中我添加了字符串不会以昏迷结束的情况。
- 更改变量名称。
好方法!然而,'看起来'布尔似乎没有必要;所有重要的是深度衡量的'深'。这种方法也不能处理输入字符串不以逗号结尾的情况(在这种情况下,它会留下最后一个元素)。 – Thriggle
@Thriggle是的!看起来只是为了我的测试目的,忘了/懒得删除它。**(它已经迟到了)**关于最后的逗号,我不明白你的意思,如果字符串昏迷完成使用它,因为它另外在开始之前添加它。我只是回答了你问的问题,我只是想引导你走一条路,我知道我无法为你提供所有用例的解决方案。 :-) – Anonymous0day
当然,如果我们想用无限制的括号嵌套工作,那么就不可能避免循环。对于一些有界的嵌套,我们可以编写一个捕获它的正则表达式。
长达1括号水平也可能是
/((?:[^(),]|\([^()]*\))+)/g
长达2括号级(可能是你的情况下)
/((?:[^(),]|\((?:[^()]|\([^()]*\))*\))+)/g
等等,与(?:[^()]|\([^()]*\))*
[^()]*
正则表达式不会让你到达你想要的位置,并且仍然允许任意的复杂度。
一种方法是迭代字符串中的每个字符,跟踪打开和关闭括号的时间,以及只有当开启和关闭括号相互抵消时逗号分开(所以你知道你'不在括号内)。
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>
[这听起来像你问的是错误的东西(http://meta.stackexchange.com/questions/66377/what -is-的-XY-问题/ 66378#66378)。 *为什么*你试图在查询结束之后拆分查询(毕竟,在形成查询之前,你想要的信息在没有奇怪字符串拆分的情况下可用)?你想要提取什么信息? –
这是不可能的JavaScript正则表达式。 –
请张贴明确的输入/输出样本。即:“__i有这个_”和“__我需要这个_”。 –