递归地提取字符串中(嵌套)括号的内容

时间:2016-11-08 02:10:00

标签: javascript arrays node.js recursion

我试图编写一个函数,将括号中包含的单词提取到自己的数组中,递归地计算嵌套括号。

因此对于"((a b)呃(一两))pi",我希望将其翻译成以下结构:

[
  [
    [
      "a",
      "b"
    ],
    "ugh",
    [
      "1",
      "2"
    ],
  ]
  "pi"
]

为此,我编写了以下功能:

function shitshow(hell) {
    var ssparts = [];
    var done = false;
    for (i in hell) {
        let part = hell[i];
        switch(part) {
            case "(":
                ssparts.push(shitshow(hell.slice(i+1)));
                break;
            case ")":
                done = true;
                break;
            default:
                ssparts.push(part);
        }
        if (done) break;
    }
    return ssparts;
}

console.log(shitshow("((developer or engineer) or (nurse or doctor)) and manager"));

它不起作用。它为我返回的数组(我在节点4上测试它):

[
  "",
  [
    "doctor"
  ],
  [],
  "developer",
  "or",
  "engineer"
]

一直在和这个摔跤。有什么想法吗?

编辑:正如@Oriol在本文的评论中提到的,我发布的代码不会产生我发布的输出。这是因为我忘了提及/包括我将RegEx的初始字符串放入一个单词数组和非字母数字符号的位置。为此表示歉意。因为@Oriol已经发布了一个可行的解决方案,所以我将这个通知包括在内,而不是更新我的代码,这样他的发布的解决方案就可以了。

4 个答案:

答案 0 :(得分:3)

我通常会做以下事情。

外部函数接收字符串作为参数,并声明用于迭代它的外部变量。

这项工作是在递归的内部函数中完成的,该函数迭代到)

这样我创建的所有新字符串都包含在返回的数组中。没有无用的工作。



function shitshow(str) {
  var i = 0;
  function main() {
    var arr = [];
    var startIndex = i;
    function addWord() {
      if (i-1 > startIndex) {
        arr.push(str.slice(startIndex, i-1));
      }
    }
    while (i < str.length) {
      switch(str[i++]) {
        case " ":
          addWord();
          startIndex = i;
          continue;
        case "(":
          arr.push(main());
          startIndex = i;
          continue;
        case ")":
          addWord();
          return arr;
      }
    }
    addWord();
    return arr;
  }
  return main();
}
console.log(shitshow("((developer or engineer ) or (nurse or doctor)) and manager"));
&#13;
div.as-console-wrapper { max-height: 100%; }
&#13;
&#13;
&#13;

答案 1 :(得分:1)

一种方法可能是将其重新格式化为JSON,然后让JSON.parse()完成所有工作。类似的东西:

&#13;
&#13;
function blah(string) {
	string = string.replace(/\(/g, "[");
	string = string.replace(/\)\s/g, "], ");
	string = string.replace(/\)/g, "]");
	string = string.replace(/\s+/, ", ");
	string = "[" + string + "]";
	string = string.replace(/[^\[\]\,\s]+/g, "\"$&\"");
	string = string.replace(/" /g, "\", ");

	return JSON.parse(string);
}

console.log(blah("((a b) ugh (one two)) pi"));
&#13;
&#13;
&#13;

编辑:修正了正则表达式的一些问题&amp;发布为运行代码。使用测试字符串。

[[["a","b"],"ugh",["one","two"]],"pi"]

就目前情况而言,如果你的字符串之间没有空格,它将无法应对。&#34;)&#34;和一个词,也不是两个&#34;)和#34;之间有空格,但如果你的输入格式是已知的并且刚性如上所述那么它就没问题了。否则,进一步正则表达式调整或替代可能会处理。

答案 2 :(得分:1)

由于Ciantic在Oriol的回答者中发现了“管理”与“管理”错误,因此一直在寻找更完整的解决方案。

function shitshow(str) {
  var i = 0;
  var trailingWhiteSpace = str[str.length - 1] === " ";
  function main() {
    var arr = [];
    var startIndex = i;
    function addWord() {
      if (i-1 > startIndex) {
        arr.push(str.slice(startIndex, i-1));
      }
    }
    while (i < str.length) {
      switch(str[i++]) {
        case " ":
          addWord();
          startIndex = i;
          continue;
        case "(":
          arr.push(main());
          startIndex = i;
          continue;
        case ")":
          addWord();
          return arr;
      }
    }
    if(!trailingWhiteSpace){
      i = i + 1;
      addWord();
    }
    return arr;
  }
  return main();
}
console.log(shitshow("((developer or engineer ) or (nurse or doctor)) and manager"));
div.as-console-wrapper { max-height: 100%; }

答案 3 :(得分:0)

对于必须处理的公式,我必须这样做。这是我对“海滩之子”答案的即兴回答:

function formulaToArray(formula='') {
  const step1 = formula
    .split(/([\(\)\+\-\*\/])/)
    .map(x => x.trim())
    .join(' ')
    .replace(/\)\s\)/g, '))')
    .replace(/\(/g, '[')
    .replace(/\)\s/g, '], ')
    .replace(/\)/g, ']');

  const step2 = '[' + step1 + ']';

  const step3 = step2
    .replace(/[^\[\]\,\s]+/g, '"$&"')
    .replace(/" /g, '", ')
    .replace(/\,[\s]+\]/g, ']');

  return JSON.parse(step3);
}

console.log(formulaToArray('((developer or engineer )or (nurse or doctor)) and manager'));
// [
//   [
//     ['developer', 'or', 'engineer'], 
//     'or', 
//     ['nurse', 'or', 'doctor']
//   ], 
//   'and', 
//   'manager'
// ]

这解决了他引用的问题:')word'和'))',尽管我猜不是')))'