我试图编写一个函数,将括号中包含的单词提取到自己的数组中,递归地计算嵌套括号。
因此对于"((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已经发布了一个可行的解决方案,所以我将这个通知包括在内,而不是更新我的代码,这样他的发布的解决方案就可以了。
答案 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;
答案 1 :(得分:1)
一种方法可能是将其重新格式化为JSON,然后让JSON.parse()完成所有工作。类似的东西:
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;
编辑:修正了正则表达式的一些问题&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'和'))',尽管我猜不是')))'