Javascript 从括号中拆分出来,用 AND /OR 做条件语句
Javascript Split from parentheses and make condition statement with AND /OR
我想从包含括号、AND 和 OR 的字符串中创建条件语句。
所以我从 Whosebug 中找到了用括号分割字符串的代码。
let array = [],
c = 0;
'(A OR B) AND C'.split(/([()])/).filter(Boolean).forEach(e =>
e == '(' ? c++ : e == ')' ? c-- : c > 0 ? array.push('(' + e + ')') : array.push(e)
);
let finalQuery = [];
while (array.length > 0) {
const condition = array.pop();
// console.log(condition)
if (condition.includes("OR")) {
let temp = condition.trim().split(" OR ");
temp.map(each => {
finalQuery.push(each);
})
} else if (condition.includes("AND")) {
let temp = condition.trim();
if (temp.includes("AND")) {
if (temp.indexOf("AND") == 0) {
if (finalQuery.length > 0) {
finalQuery = finalQuery.map(x => x + " " + temp.replace("AND", ""))
}
} else if (temp.indexOf("AND") == temp.length - 3) {
if (finalQuery.length > 0) {
finalQuery = finalQuery.map(x => temp.replace("AND", "") + ' ' + x)
}
}
}
}
console.log(finalQuery)
}
我试过上面的代码。
但是没用。
我想要如下结果。
输入:(A OR B) AND (C OR D)
输出:A C OR A D OR B C OR B D
输入:(A OR B) AND (C OR D) AND (E OR F)
输出:A C E OR A C F OR A D E OR A D F OR B C E OR B C F OR B D E OR B D F
谁能帮我一下?
仅适用于 A AND/OR B AND/OR C ...
、
的格式
让我们假设
- A 是 token 同样 B 是 token 太
- 操作只是
AND
和OR
之一
expression = token opertaor token
。 - (1)
我将所有 expressions 评估为 token 作为字符串。我有一些规则:
A OR B
-> A,B
(标记为字符串)
A AND B
-> AB
- 那么,
A,B AND C
可以计算为AC,BC
通过括号 (
和 )
解析并获取表达式,并对其进行评估。
例如,(A AND B) OR C
被评估为 AB OR C
并再次计算为 AB,C
。现在我们可以通过上面的 (1)
评估所有表达式
这是代码。试一试:
function is_exp(s){
return s.indexOf(' OR ') !== -1 || s.indexOf(' AND ') !== -1;
}
// return "exp oper exp" to evaluated exp
function eval(s) {
// OR operation
if (s.indexOf('OR') != -1) {
var i = s.indexOf('OR');
var first = s.slice(0, i - 1);
var second = s.slice(i + 3);
return [first, second].toString(); // merge
}
// AND operation
else if (s.indexOf('AND') != -1) {
var i = s.indexOf('AND');
var first = s.slice(0, i - 1).split(',');
var second = s.slice(i + 4).split(',');
var result = [];
for(var f0 of first) {
for(var s0 of second) {
result.push(f0 + s0);
}
}
return result.toString();
}
// wrong and fail
else {
return "";
}
}
function _calculate(s) {
var l = -1, r = Infinity;
var tokens = [];
var opers = [];
while (l < s.length) {
l = s.indexOf('(', l+1);
if (r+1 < l) {
opers.push(s.slice(r+1, l).replace(/\s/gi, ''));
}
r = s.indexOf(')', l);
if (l == -1 || r == -1) break;
var exp = s.slice(l+1, r);
tokens.push(is_exp(exp) ? eval(exp) : exp); // if it is expression, evaluted it.
}
// evaluate all chained elements
var result = tokens[0];
for(var i=1; i < tokens.length; ++i) {
result = eval(result + ' ' + opers[i-1] + ' ' + tokens[i]);
}
// make string as good to read
var lst = result.split(',');
lst = lst.map((v) => (v.split('').join(' '))); // "ABC" => "A B C"
return lst.join(' or '); // add "OR" between all tokens
}
function calculate() {
var input = document.getElementById('input');
var output = document.getElementById('output');
output.value = _calculate(input.value);
}
document.addEventListener('DOMContentLoaded', calculate);
textarea { width: 100%; display: block; margin: 5px auto; }
<textarea id="input" rows="2">(A OR B) AND (C OR D)</textarea>
<button onclick="calculate()">Run</button>
<textarea id="output" rows="2" disabled readonly></textarea>
但是,在我的代码中不适用于 (A AND (B OR C)) OR D
。
如果你想处理上面的情况,我想可以用堆栈或递归来解决,并且在括号上解析更完美。
我想从包含括号、AND 和 OR 的字符串中创建条件语句。
所以我从 Whosebug 中找到了用括号分割字符串的代码。
let array = [],
c = 0;
'(A OR B) AND C'.split(/([()])/).filter(Boolean).forEach(e =>
e == '(' ? c++ : e == ')' ? c-- : c > 0 ? array.push('(' + e + ')') : array.push(e)
);
let finalQuery = [];
while (array.length > 0) {
const condition = array.pop();
// console.log(condition)
if (condition.includes("OR")) {
let temp = condition.trim().split(" OR ");
temp.map(each => {
finalQuery.push(each);
})
} else if (condition.includes("AND")) {
let temp = condition.trim();
if (temp.includes("AND")) {
if (temp.indexOf("AND") == 0) {
if (finalQuery.length > 0) {
finalQuery = finalQuery.map(x => x + " " + temp.replace("AND", ""))
}
} else if (temp.indexOf("AND") == temp.length - 3) {
if (finalQuery.length > 0) {
finalQuery = finalQuery.map(x => temp.replace("AND", "") + ' ' + x)
}
}
}
}
console.log(finalQuery)
}
我试过上面的代码。
但是没用。
我想要如下结果。
输入:(A OR B) AND (C OR D)
输出:A C OR A D OR B C OR B D
输入:(A OR B) AND (C OR D) AND (E OR F)
输出:A C E OR A C F OR A D E OR A D F OR B C E OR B C F OR B D E OR B D F
谁能帮我一下?
仅适用于 A AND/OR B AND/OR C ...
、
让我们假设
- A 是 token 同样 B 是 token 太
- 操作只是
AND
和OR
之一
expression = token opertaor token
。 - (1)
我将所有 expressions 评估为 token 作为字符串。我有一些规则:
A OR B
->A,B
(标记为字符串)A AND B
->AB
- 那么,
A,B AND C
可以计算为AC,BC
通过括号 (
和 )
解析并获取表达式,并对其进行评估。
例如,(A AND B) OR C
被评估为 AB OR C
并再次计算为 AB,C
。现在我们可以通过上面的 (1)
这是代码。试一试:
function is_exp(s){
return s.indexOf(' OR ') !== -1 || s.indexOf(' AND ') !== -1;
}
// return "exp oper exp" to evaluated exp
function eval(s) {
// OR operation
if (s.indexOf('OR') != -1) {
var i = s.indexOf('OR');
var first = s.slice(0, i - 1);
var second = s.slice(i + 3);
return [first, second].toString(); // merge
}
// AND operation
else if (s.indexOf('AND') != -1) {
var i = s.indexOf('AND');
var first = s.slice(0, i - 1).split(',');
var second = s.slice(i + 4).split(',');
var result = [];
for(var f0 of first) {
for(var s0 of second) {
result.push(f0 + s0);
}
}
return result.toString();
}
// wrong and fail
else {
return "";
}
}
function _calculate(s) {
var l = -1, r = Infinity;
var tokens = [];
var opers = [];
while (l < s.length) {
l = s.indexOf('(', l+1);
if (r+1 < l) {
opers.push(s.slice(r+1, l).replace(/\s/gi, ''));
}
r = s.indexOf(')', l);
if (l == -1 || r == -1) break;
var exp = s.slice(l+1, r);
tokens.push(is_exp(exp) ? eval(exp) : exp); // if it is expression, evaluted it.
}
// evaluate all chained elements
var result = tokens[0];
for(var i=1; i < tokens.length; ++i) {
result = eval(result + ' ' + opers[i-1] + ' ' + tokens[i]);
}
// make string as good to read
var lst = result.split(',');
lst = lst.map((v) => (v.split('').join(' '))); // "ABC" => "A B C"
return lst.join(' or '); // add "OR" between all tokens
}
function calculate() {
var input = document.getElementById('input');
var output = document.getElementById('output');
output.value = _calculate(input.value);
}
document.addEventListener('DOMContentLoaded', calculate);
textarea { width: 100%; display: block; margin: 5px auto; }
<textarea id="input" rows="2">(A OR B) AND (C OR D)</textarea>
<button onclick="calculate()">Run</button>
<textarea id="output" rows="2" disabled readonly></textarea>
但是,在我的代码中不适用于 (A AND (B OR C)) OR D
。
如果你想处理上面的情况,我想可以用堆栈或递归来解决,并且在括号上解析更完美。