1

我想用一个特殊的字符串创建一个数组。格式如下:

(a),(b),(c(d,e)),(f(g(h,i,j)))

数组应该是这样的:

(一) | (b) | (c(d,e)) | (f(g(h,i,j)))

使用该split()功能不是一个好主意,因为它给了我这样的东西:

(一) | (b) | (c(d | e)) | (f(g(h | i | j)))

有任何想法吗?

4

4 回答 4

3

这是一种可能的简短解决方案:

function strSplit(str, x) {
    return x = 0, str.replace(/./g, function(c, i, a) {
        return c === "(" ? (x++, c) :
               c === ")" && i < a.length - 1 && --x === 0 ? c + "|" : c;
    }).split("|,");
}

strSplit("(a),(b),(c(d,e)),(f(g(h,i,j),k(l,m),n))");
// >> ["(a)", "(b)", "(c(d,e))", "(f(g(h,i,j),k(l,m),n))"]

演示:http: //jsfiddle.net/WRdAC/


为了使代码更清晰,这里是完整的变体:

function strSplit(str) {
    var x = 0;
    return str.replace(/./g, function(c, i, a) {
        if (c === "(") {
            x++;
        } else if (c === ")" && i < a.length - 1 && --x === 0) {
            return c + "|";
        }
        return c;
    }).split("|,");
}
于 2013-01-21T08:44:57.133 回答
3

如何计算左括号的数量?如果计数为零,则可以安全拆分。

var
  input = '(a),(b),(c(d,e)),(f(g(h,i,j)))',
  i = 0,
  lim = input.length,
  output = [],
  count = 0,
  stack = [],
  c;

for (; i < lim; i += 1) {
  c = input.charAt(i);

  switch (c) {
    case '(':
      count += 1;
      break;

    case ')':
      count -= 1;
      break;

    case ',':
      if (count === 0) {
        output.push(stack.join(''));
        stack = [];
        continue;
      }
      break;
  }

  stack.push(c);
}

if (stack.length > 0) {
  output.push(stack.join(''));
}

console.log(output); // ["(a)", "(b)", "(c(d,e))", "(f(g(h,i,j)))"] 

http://jsbin.com/otofog/1/


或者(如果您的目标不是 IE < 9):

function mySplit(input) {
  var count = 0, output = [], stack;

  stack = input.split('').reduce(function (stack, c) {
    switch (c) {
      case '(': count += 1; break;
      case ')': count -= 1; break;
      case ',':
        if (count === 0) {
          output.push(stack.join(''));
          return [];
        }
    }

    stack.push(c);
    return stack;
  }, []);

  if (stack.length > 0) {
    output.push(stack.join(''));
  }

  return output;
}

console.log( mySplit('(a),(b),(c(d,e)),(f(g(h,i,j)))') );

http://jsbin.com/ohasuc/1/

于 2013-01-21T09:00:57.747 回答
0

像这样的东西:

var s = "(a),(b),(c(d,e)),(f(g(h,i,j)))";
var a = s.split("),");
for (var i = 0; i < a.length - 1; i++)
  a[i] = a[i] + ")";

更复杂的结构可能需要这样:

var s = "(a),(b),(c(d,e)),(f(g(h,i,j),k(l,m),n))";
var a = s.split("),(");
for (var i = 0; i < a.length - 1; i++)
  a[i] = a[i] + ")";
for (var i = 1; i < a.length; i++)
  a[i] = "(" + a[i];
于 2013-01-21T08:53:36.943 回答
0

此功能完全符合您的要求:

function parseStrToArr(str){
  var pairs = 0;
  var arr   = [];
  var chars = '';

  for(var i = 0, l = str.length; i < l; i++){
    var char = str[i];

    switch(char){
      case '(': pairs++; break;
      case ')': pairs--; break;
    }

    if(!pairs){
      if(chars){
        arr.push(chars + char);
        chars = '';
      }
    }
    else{
      chars += char;
    }
  }

  return arr;
}

关键是匹配成对的括号。即使您删除逗号,此算法也将起作用。

于 2013-01-21T09:27:39.463 回答