Javascript 如何将字符串拆分为'';或';[|]和#x27;除非'';在';{}';
我搜索正则表达式以拆分以下字符串:Javascript 如何将字符串拆分为'';或';[|]和#x27;除非'';在';{}';,javascript,regex,Javascript,Regex,我搜索正则表达式以拆分以下字符串: aaa[bbb,ccc[ddd,{eee:1,mmm:999}],nnn[0,3]] aaa[bbb,ccc[ddd,{eee:1, mmm:[123,555]}],nnn[0,3]] aaa[bbb, ccc[ddd, ddd],nnn[0,3]] aaa[bbb,ddd[0,3]] 通过“[”或“]”或“,”,除非“,”在“{}”中。例如:将'aaa[bbb,ccc[ddd'拆分为aaa,bbb,ccc,ddd是允许的,但不允许{eee:1,mmm:99
aaa[bbb,ccc[ddd,{eee:1,mmm:999}],nnn[0,3]]
aaa[bbb,ccc[ddd,{eee:1, mmm:[123,555]}],nnn[0,3]]
aaa[bbb, ccc[ddd, ddd],nnn[0,3]]
aaa[bbb,ddd[0,3]]
通过“[”或“]”或“,”,除非“,”在“{}”中。例如:将'aaa[bbb,ccc[ddd'拆分为aaa,bbb,ccc,ddd是允许的,但不允许{eee:1,mmm:999}
结果是:
aaa, bbb, ccc, ddd, {eee:1,mmm:999}, nnn, 0, 3
aaa, bbb, ccc, ddd, {eee:1, mmm:[123,555]}], nnn, 0, 3
aaa, bbb, ccc, ddd, ddd, nnn, 0, 3
aaa, bbb, ddd, 0, 3
我已经读过很多其他的问题,但是我不能修改正则表达式,因为这里有我想要的
表达式的目标语言是javascript。使用正则表达式和处理无限嵌套大括号是不可能的;您需要一个基于堆栈的解析器。非正则表达式的方法是只编写一个循环,逐字符检查字符串。当它遇到
{
,递增一个变量。当它遇到}
时,取消递增一个变量。当它遇到,
并且您正在递增/取消递增的变量为零时,将,
的位置添加到列表中。完成后,您就有了要拆分字符串的位置列表
我假设在打开大括号之前没有任何右大括号出现,否则您可能希望忽略错误放置的右大括号,而不是将变量反增量为负数。Perl/PCRE regex也应该在JS中工作(只要{}没有嵌套): 输出:
aaa, bbb, ccc, ddd, {eee:1,mmm:999}, nnn, 0, 3,
aaa, bbb, ccc, ddd, {eee:1, mmm:[123,555]}, nnn, 0, 3,
aaa, bbb, ccc, ddd, ddd, nnn, 0, 3,
aaa, bbb, ddd, 0, 3
粗略翻译成JavaScript:
var input =
"aaa[bbb,ccc[ddd,{eee:1,mmm:999}],nnn[0,3]]\n" +
"aaa[bbb,ccc[ddd,{eee:1, mmm:[123,555]}],nnn[0,3]]\n" +
"aaa[bbb, ccc[ddd, ddd],nnn[0,3]]\n" +
"aaa[bbb,ddd[0,3]]";
var re = /[^][,{}]+|\{[^}]*}/g;
var result = [];
while (!!(match = re.exec(input)))
{
result.push(match[0]);
}
// Using <<value>> rather than just a comma, for clarity around
// whether and how "{...}" was processed or not.
write("<<" + result.join(">><<") + ">>");
把{东西}分开,剩下的分开-
function customRx(s){
s= s.replace(/[\[\],\s]+$/g,'');
var Rx=/,?(\{[^}]+\}),?/g, Rs=/[\[\],\s]+/, Rc=/^,|,$/g;
var A= [], i= 0, M, z= 0;
while((M= Rx.exec(s))!= null){
i= M.index;
if(i> z){
A.push(s.substring(z, i).split(Rs));
}
z= Rx.lastIndex;
A.push(s.substring(i, z).replace(Rc,''));
}
if(s.length> z){
A.push(s.substring(z).split(Rs));
}
return A;
}
//试验
var s1= 'aaa[bbb,ccc[ddd,{eee:1,mmm:999}],nnn[0,3]]'+
'aaa[bbb,ccc[ddd,{eee:1, mmm:[123,555]}],nnn[0,3]]'+
'aaa[bbb, ccc[ddd, ddd],nnn[0,3]]'+
'aaa[bbb,ddd[0,3]]';
警报(customRx(s1).join(',')
返回值(添加换行符)>
aaa,bbb,ccc,ddd,{eee:1,mmm:999}
nnn,0,3,aaa,bbb,ccc,ddd,{eee:1,mmm:[123555]}
nnn,0,3,aaa,bbb,ccc,ddd,ddd,nnn
0,3,aaa,bbb,ddd,0,3假设您正在逐行处理文本,并且大括号不能嵌套,此拆分正则表达式应该可以工作:
/ *[\[\],]+ *(?=[^{}]*(?:\{[^{}]*\}[^{}]*)*$)/
第一部分--
*[\[\],]+*
--匹配一个或多个[
,]
或,
和任何周围的空格。其余的是一个前瞻性语句,它断言,如果匹配字符前面有大括号,它们将以平衡的对出现。如果文本格式正确,则确保匹配不会发生在大括号内。正则表达式不会“执行”语言解析:-(是否有{}{}的内部?我不清楚你的“结果”是什么。你给我们看的是字符串吗?一个包含子数组作为条目的数组?因为当正则表达式引用PCRE/等时它不是真的。请看我的答案。它支持/[^][,{}]+\{[^}]*}/
tho,这一点也不奇怪。@Qtax:这能处理嵌套的大括号吗?你可以嵌套除{}之外的任何东西,似乎是这样。@SLaks:它似乎非常接近,至少在提供的测试数据(和问题陈述)和我(可能是天真的)翻译的范围内(我将在稍后编辑)。为了避免疑问:我不是说我会这样做(除了扫描断点之外,我根本不想使用regexp),只是提供了一个粗略的翻译,因为Qtax刚刚给出了Perl/PCRE.+1我可能不会逐个字符(我会用regexp沿着[{,[\]}]
的行扫描断点),但是,是的,我想我可能会这样做,而不是试图在一个可能最适合其他逻辑的问题上强制使用纯regexp解决方案。/*[][,]+*(?![^{]*})/
,如果字符串没有格式错误
var s1= 'aaa[bbb,ccc[ddd,{eee:1,mmm:999}],nnn[0,3]]'+
'aaa[bbb,ccc[ddd,{eee:1, mmm:[123,555]}],nnn[0,3]]'+
'aaa[bbb, ccc[ddd, ddd],nnn[0,3]]'+
'aaa[bbb,ddd[0,3]]';
/ *[\[\],]+ *(?=[^{}]*(?:\{[^{}]*\}[^{}]*)*$)/