Javascript 正则表达式按逗号拆分,字符串或列表“[]内除外`

Javascript 正则表达式按逗号拆分,字符串或列表“[]内除外`,javascript,regex,split,Javascript,Regex,Split,给定一个字符串,例如 1,'str,ing',[1,2,3,4,5,'str,ing']],'st[rin,g][' 我想根据逗号进行拆分,但不包括内部字符串或方括号中的逗号 1 'str,ing' [1,2,3,4,5,'str,ing']] st[rin,g][' 我得到的最接近的是,(?=(?:[^'[\]]*['“[\][^'[\]]*['”[\]]*['[\]]]]*$),但这并没有意识到]不会关闭'Regex是一种无上下文的语言,这意味着它无法解析基于深度的逻辑(例如嵌套数组)。如果

给定一个字符串,例如

1,'str,ing',[1,2,3,4,5,'str,ing']],'st[rin,g]['

我想根据逗号进行拆分,但不包括内部字符串或方括号中的逗号

1

'str,ing'

[1,2,3,4,5,'str,ing']]

st[rin,g]['


我得到的最接近的是
,(?=(?:[^'[\]]*['“[\][^'[\]]*['”[\]]*['[\]]]]*$)
,但这并没有意识到
]
不会关闭
'

Regex是一种无上下文的语言,这意味着它无法解析基于深度的逻辑(例如嵌套数组)。如果您处理的是格式不正确的数据,则必须对数据进行一些假设,然后手动逐步处理数据

下面是一个运行的示例,假设每个
[
都应该有一个匹配的
]
,并且
{}
不是特殊的。(检查字符串结尾以防止失控循环)

var str=“1,'str,ing',[1,2,3,4,5,'str,ing'],'st[rin,g]['”;
var起始指数=0;
var部分=[];

for(index=0;indexRegex是一种无上下文语言,这意味着它无法解析基于深度的逻辑(例如,嵌套数组)。如果您处理的是格式错误的数据,则必须对数据进行一些假设,并手动单步遍历数据

下面是一个运行的示例,假设每个
[
都应该有一个匹配的
]
,并且
{}
不是特殊的。(检查字符串结尾以防止失控循环)

var str=“1,'str,ing',[1,2,3,4,5,'str,ing'],'st[rin,g]['”;
var起始指数=0;
var部分=[];

对于(index=0;index,基于上面@Terza的答案,添加了一些逻辑来处理字符串内的转义引号和字符串内的括号

类参数拆分器{
构造函数(字符串){
this.string=string;
这个指数=-1;
这个.startIndex=0;
this.params=[];
}
splitByParams(){
设深度=0;
而(this.nextIndex()&&(!this.atQuote()| | this.skipQuote()){
让char=this.string[this.index];
如果(字符=='[')
深度++;
else if(char==']')
深度--;
else if(char==','&&!depth){
this.addParam();
this.startIndex=this.index+1;
}
}
this.addParam();
返回此.params;
}
findIndex(regex,start){//返回匹配的-1或索引
让index=this.string.substring(start.search)(regex);
返回索引>=0?索引+开始:-1;
}
nextIndex(){
this.index=this.findIndex(/[,'“[\]]/,this.index+1);
返回此。索引!==-1;
}
atQuote(){
让char=this.string[this.index];
返回char==''”| char===''”;
}
斯基普奎特(){
让char=this.string[this.index];
this.index=this.findIndex(char=='”?/[^\\]“/:/[^\\]'/,this.index+1)+1;
返回此.index;
}
addParam(){
this.params.push(this.string.substring(this.startIndex,this.index>0?this.index:this.string.length).trim());
}
}
让run=string=>newparamspilter(string.splitByParams();
让输入=“1,'str,ing',[1,2,[3,4,5,'str,ing']],'st[rin,g][','text\\'moretext',['two','two','two','twree','4”;

log(run(input));
基于上面@Terza的回答,添加了一些逻辑来处理字符串内的转义引号和字符串内的括号

类参数拆分器{
构造函数(字符串){
this.string=string;
这个指数=-1;
这个.startIndex=0;
this.params=[];
}
splitByParams(){
设深度=0;
而(this.nextIndex()&&(!this.atQuote()| | this.skipQuote()){
让char=this.string[this.index];
如果(字符=='[')
深度++;
else if(char==']')
深度--;
else if(char==','&&!depth){
this.addParam();
this.startIndex=this.index+1;
}
}
this.addParam();
返回此.params;
}
findIndex(regex,start){//返回匹配的-1或索引
让index=this.string.substring(start.search)(regex);
返回索引>=0?索引+开始:-1;
}
nextIndex(){
this.index=this.findIndex(/[,'“[\]]/,this.index+1);
返回此。索引!==-1;
}
atQuote(){
让char=this.string[this.index];
返回char==''”| char===''”;
}
斯基普奎特(){
让char=this.string[this.index];
this.index=this.findIndex(char=='”?/[^\\]“/:/[^\\]'/,this.index+1)+1;
返回此.index;
}
addParam(){
this.params.push(this.string.substring(this.startIndex,this.index>0?this.index:this.string.length).trim());
}
}
让run=string=>newparamspilter(string.splitByParams();
让输入=“1,'str,ing',[1,2,[3,4,5,'str,ing']],'st[rin,g][','text\\'moretext',['two','two','two','twree','4”;

console.log(run(input));
查找csv解析器。您的字符串格式似乎是分层的。如果是这样,则不可能构造一个适用于所有边缘情况的正则表达式,并且您不应该依赖一个似乎适用于“几乎”的正则表达式“一切。你需要编写一个适当的词法递归下降解析器来处理分层字符串格式。不要使用正则表达式,但如果必须这样做的话:
'[^']*.'(\[(?:[^][*.*(?1))*].[^,\s]+[^,]*.
regex
包(不是
re
包)匹配,而不是拆分。你尝试过JSON.parse(”)吗?”['+mystring+']')@Shanimal,这行不通,因为内部不一定是有效的json。例如,我可以让字符串作为
1,2,垃圾
查找csv解析器。您的字符串格式似乎是分层的。如果是这样,就不可能构造一个适用于每种边缘情况的正则表达式,您不应该依赖一个似乎适用于它的正则表达式“几乎”一切。你需要写一个p