我确实意识到这个答案已经晚了 8 年,但我想我会添加自己的贡献,因为这个问题出现在我正在从事的项目中。就我而言,我使用的是 Nodejs,但这个解决方案也应该适用于浏览器。
let parens = /\(([0-9+\-*/\^ .]+)\)/ // Regex for identifying parenthetical expressions
let exp = /(\d+(?:\.\d+)?) ?\^ ?(\d+(?:\.\d+)?)/ // Regex for identifying exponentials (x ^ y)
let mul = /(\d+(?:\.\d+)?) ?\* ?(\d+(?:\.\d+)?)/ // Regex for identifying multiplication (x * y)
let div = /(\d+(?:\.\d+)?) ?\/ ?(\d+(?:\.\d+)?)/ // Regex for identifying division (x / y)
let add = /(\d+(?:\.\d+)?) ?\+ ?(\d+(?:\.\d+)?)/ // Regex for identifying addition (x + y)
let sub = /(\d+(?:\.\d+)?) ?- ?(\d+(?:\.\d+)?)/ // Regex for identifying subtraction (x - y)
/**
* Evaluates a numerical expression as a string and returns a Number
* Follows standard PEMDAS operation ordering
* @param {String} expr Numerical expression input
* @returns {Number} Result of expression
*/
function evaluate(expr)
{
if(isNaN(Number(expr)))
{
if(parens.test(expr))
{
let newExpr = expr.replace(parens, function(match, subExpr) {
return evaluate(subExpr);
});
return evaluate(newExpr);
}
else if(exp.test(expr))
{
let newExpr = expr.replace(exp, function(match, base, pow) {
return Math.pow(Number(base), Number(pow));
});
return evaluate(newExpr);
}
else if(mul.test(expr))
{
let newExpr = expr.replace(mul, function(match, a, b) {
return Number(a) * Number(b);
});
return evaluate(newExpr);
}
else if(div.test(expr))
{
let newExpr = expr.replace(div, function(match, a, b) {
if(b != 0)
return Number(a) / Number(b);
else
throw new Error('Division by zero');
});
return evaluate(newExpr);
}
else if(add.test(expr))
{
let newExpr = expr.replace(add, function(match, a, b) {
return Number(a) + Number(b);
});
return evaluate(newExpr);
}
else if(sub.test(expr))
{
let newExpr = expr.replace(sub, function(match, a, b) {
return Number(a) - Number(b);
});
return evaluate(newExpr);
}
else
{
return expr;
}
}
return Number(expr);
}
// Example usage
//console.log(evaluate("2 + 4*(30/5) - 34 + 45/2"));
在原始帖子中,可以使用 String.replace() 替换变量以提供类似于片段中的示例用法的字符串。