1

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
2
  • Are you asking to turn the math equation string into what it evaluates to? Commented Jan 29, 2022 at 17:49
  • There's nothing built into javascript for this, but various libraries are available. Or you can implement it yourself. Commented Jan 29, 2022 at 17:52

2 Answers 2

1

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')"));

Sign up to request clarification or add additional context in comments.

6 Comments

thanks, but it doesn't seem to be working completely. when i do checkAllowedCommands("(12)") or checkAllowedCommands("sin(10)"), it returns false. it seems like it doesn't work if the input starts or ends with ( or ).
You were right. Splitting with the above RegEx added an empty string to the array and the empty string doesn't exist in the list of allowed commands. I added a filter after the split for non empty commands.
it still doesn't seem to work completely. addition and subtraction still doesn't work
I thought you'd figure it out. You just need to add math operators to the following code: var commands = mathExpression.replace(/([()/*+-])/g, " $1 ").split(" ").filter(v => v);
one last thing- is there a way to make it work with scientific notation? something like 1e5 or 1e+5
|
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.