如何用','或'[|]'拆分字符串,除非','在'{}'中

时间:2010-03-18 17:12:58

标签: 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]]

by'['或']'或','除非','在'{}'中。例如:拆分'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。

5 个答案:

答案 0 :(得分:2)

使用正则表达式并处理无限制的嵌套大括号是不可能的;你需要一个基于堆栈的解析器。

答案 1 :(得分:1)

非正则表达式的方法是编写一个循环,逐个字符地检查字符串。遇到{时,增加变量。当遇到}时,减去变量。当遇到,并且您正在递增/递减的变量为零时,将,的位置添加到列表中。完成后,您将获得要拆分字符串的位置列表。

我假设在打开大括号}之前没有任何结束大括号{,否则你可能想要忽略错位的大括号,而不是将你的变量递减到底片

答案 2 :(得分:1)

Perl / PCRE正则表达式也应该在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]]';

@r = /[^][,{}]+|\{[^}]*}/g;
print join ", ", @r;

输出:

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(">><<") + ">>");

目前尚不清楚问题中输入或结果数据中的换行符是什么意思。在上面,它们是输入数据中的换行符,然后在结果中没有特别处理。如果需要特殊处理,OP可以进行适当的编辑。因此,这是上述结果(同样,使用<<>>作为分隔符,而不是,,以明确{...}是否得到处理):

<<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>>

答案 3 :(得分:0)

分开其余部分时将{stuff}分开 -

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;
}

// test

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]]';

alert(customRx(s1).join(','));

返回值(已添加换行符)&gt;

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

答案 4 :(得分:0)

假设您正在逐行处理文本,并且无法嵌套大括号,则此分割正则表达式应该有效:

/ *[\[\],]+ *(?=[^{}]*(?:\{[^{}]*\}[^{}]*)*$)/

第一部分 - *[\[\],]+ * - 匹配[],中的一个或多个以及任何周围空格。剩下的就是一个先行者,断言如果匹配的字符前面有任何大括号,它们就是平衡对。如果文本格式正确,则可确保在一对大括号内不会发生匹配。