Is there a way to parse math equations as input using JavaScript?
for example, when a user enters "10-25" as input, it is parsed to -15
I tried using eval, which works, but it allows users to run all JavaScript code, not just math equations.
If it's possible, I'd like to also allow some functions, like sin(), cos(), and degreesToRadians(), but not all functions.
examples
"5" //returns 5
"12-20" //returns -8
"3/2" //returns 1.5
"sin(3.14)" //returns 0.00159265292
"sin(degreesToRadians(180/2)) * 10" //returns 10
"alert('hi')" //doesn't work
You can split expression by math operations and check them.
Next code does it for: ( ) / *
mathExpression.replace(/([()/*])/g, " $1 ").split(" ").filter(v => v);
var allowedCommands = ["(", ")", /^\d*\.?\d*e?$/, "*", "/", "+", "-", "sin", "cos", "degreesToRadians"];
function checkCommand(arg) {
return allowedCommands.some(v => {
if (v instanceof RegExp) {
return v.test(arg)
} else {
return v == arg;
}
});
}
function checkAllowedCommands(mathExpression) {
var commands = mathExpression.replace(/([()/*+-])/g, " $1 ").split(" ").filter(v => v);
var filterNotAllowedCommands = commands.filter(v => !checkCommand(v));
return filterNotAllowedCommands.length == 0;
}
console.log(checkCommand("degreesToRadians"));
console.log(checkCommand("234"));
console.info("right expression");
console.info(checkAllowedCommands("sin(degreesToRadians(180/2)) * 10"));
console.info(checkAllowedCommands("(1.2e-6)"))
console.info(checkAllowedCommands("sin(1+2)"));
console.warn("wong expression");
console.info(checkAllowedCommands("alert('hi')"));
Perhaps something like this package: https://www.npmjs.com/package/nerdamer
I've used Nerdamer in a few projects in the past, and it's pretty solid. Short of that, there's no "simple" way to do it short of implementing your own mini-parser that I know of.