如何解析和评估字符串(例如'1+1'
)中的数学表达式而不调用eval(string)
产生其数值?
在那个例子中,我希望函数接受'1+1'
并返回2
.
如何解析和评估字符串(例如'1+1'
)中的数学表达式而不调用eval(string)
产生其数值?
在那个例子中,我希望函数接受'1+1'
并返回2
.
您可以使用JavaScript Expression Evaluator library,它允许您执行以下操作:
Parser.evaluate("2 ^ x", { x: 3 });
或者mathjs,它允许以下内容:
math.eval('sin(45 deg) ^ 2');
我最终为我的一个项目选择了 mathjs。
您可以轻松地执行 + 或 - 操作:
function addbits(s) {
var total = 0,
s = s.match(/[+\-]*(\.\d+|\d+(\.\d+)?)/g) || [];
while (s.length) {
total += parseFloat(s.shift());
}
return total;
}
var string = '1+23+4+5-30';
console.log(
addbits(string)
)
更复杂的数学使 eval 更具吸引力——当然也更容易编写。
有人必须解析该字符串。如果它不是解释器(通过eval
),那么它需要是你,编写一个解析例程来提取数字、运算符以及你想要在数学表达式中支持的任何其他内容。
所以,不,没有任何(简单)方法没有eval
. 如果您担心安全性(因为您解析的输入不是来自您控制的源),也许您可以在将输入的格式(通过白名单正则表达式过滤器)传递给eval
?
@kennebec 出色答案的替代方法,使用较短的正则表达式并允许运算符之间存在空格
function addbits(s) {
var total = 0;
s = s.replace(/\s/g, '').match(/[+\-]?([0-9\.\s]+)/g) || [];
while(s.length) total += parseFloat(s.shift());
return total;
}
使用它就像
addbits('5 + 30 - 25.1 + 11');
更新
这是一个更优化的版本
function addbits(s) {
return (s.replace(/\s/g, '').match(/[+\-]?([0-9\.]+)/g) || [])
.reduce(function(sum, value) {
return parseFloat(sum) + parseFloat(value);
});
}
我出于同样的目的创建了BigEval。
在求解表达式时,它的性能与Eval()
%、^、&、**(幂)和 ! 等运算符完全相同并支持。(阶乘)。您还可以在表达式中使用函数和常量(或说变量)。该表达式以PEMDAS 顺序求解,这在包括 JavaScript 在内的编程语言中很常见。
var Obj = new BigEval();
var result = Obj.exec("5! + 6.6e3 * (PI + E)"); // 38795.17158152233
var result2 = Obj.exec("sin(45 * deg)**2 + cos(pi / 4)**2"); // 1
var result3 = Obj.exec("0 & -7 ^ -7 - 0%1 + 6%2"); //-7
如果您处理具有任意精度的数字,也可以使用这些 Big Number 库进行算术运算。