zDomi
zDomi

Reputation: 33

Check if string is a mathematical expression in JavaScript

I want to know an easy way of checking if a string is a mathematical expression. As an example, Google (and other search engines) use this when you search.

PS: I don't necessarily want to check stuff like sin, cos, etc.

Example: 2+2 should return true but letters+somethingelse should return false

Thanks!

Upvotes: 1

Views: 9691

Answers (5)

adong Xiao
adong Xiao

Reputation: 1

you can use eval(expression) to execute it, and you need to use "trycatch" to wrap the code block. if it catches an error, the expression should be invalid

Upvotes: 0

Patrick Roberts
Patrick Roberts

Reputation: 51916

Using complex-js, you can wrap Complex.compile() in a try/catch statement:

function isMathExpression (str) {
  try {
    Complex.compile(str);
  } catch (error) {
    return false;
  }
  
  return true;
}

console.log(isMathExpression('2+2'))
console.log(isMathExpression('foo+bar'))
console.log(isMathExpression('sin(5)+sqrt(2/5i)'))
<script src="https://unpkg.com/[email protected]/dst/complex.min.js"></script>

The grammar for this parser is here, if you're interested in seeing what constructs it supports.

Full disclosure, I am the author of this library

Upvotes: 3

sufiyan gani
sufiyan gani

Reputation: 31

You can use math.js for this.

For your case use math.evaluate(expression)

If you want to check whether an expression(containing variables) is mathematically valid use math.parse(expression) E.g. math.parse('a+b') is valid but math.parse('b+') will throw an exception.

function isValidMathExpression(expr){
        try{
            math.parse(expr);
            return true;
        }
        catch(ex){
            return false;
        }
    }

Upvotes: 3

user9366559
user9366559

Reputation:

Here's a regex that can do what I think you're looking for:

/(?:(?:^|[-+_*/])(?:\s*-?\d+(\.\d+)?(?:[eE][+-]?\d+)?\s*))+$/

https://regex101.com/r/w74GSk/4

It matches a number, optionally negative, with an optional decimal number followed by zero or more operator/number pairs.

It also allows for whitespace between numbers and operators.

const re = /(?:(?:^|[-+_*/])(?:\s*-?\d+(\.\d+)?(?:[eE][+-]?\d+)?\s*))+$/;

function test(s) {
  console.log("%s is valid? %s", s, re.test(s));
}

// valid
test(" 1 ");
test("1 + 2");
test(" 1 * 2 * 3 ");
test("-1 * 2 - -3");
test("-1 * 2 - -3e4");
test("-1 * 2 - -3.5E6");

// invalid
test("1 +");
test("1 + foo");

This may need to be expanded, based on what you want to allow. One thing it does not handle is parentheses to override operator precedence.

Upvotes: 7

Helam
Helam

Reputation: 1505

You can use Regular Expressions. Go to that link to learn more about them.

This is a very simple example that just checks for a number and then a +, -, *, or / and then another number. You will want to adjust it and add to it to suit your needs.

/\d+(\+|\-|\*|\/)\d+/.test("1+2") // returns true
/\d+(\+|\-|\*|\/)\d+/.test("a+b") // returns false

Upvotes: 0

Related Questions