Learner
Learner

Reputation: 21393

Regex to validate and extract data from a calculation

I am trying to find out a regular expression where I can validate the input and also extract required information from input.

My input contains a simple calculation like addition, subtraction, multiplication and division.

For example: if input is addtion say 7.01+9.05

var input = '7.01+9.05';

var pattern = /^-?\d+\.?\d+[-+*\/]-?\d+\.?\d+$/
var sign;
if (input.match(pattern)) {
    var matches = pattern.exec(input);

    var left = // logic to extract value 7.01 using matches variable;
    var right = // logic to extract value 9.05 using matches variable;
    var sing = // logic to extract symbol + using matches variable;
}

I have used the regular expression which I found from this post : Calculator Regular Expression with decimal point and minus sign

Can you please help me how to extract the required data in above code?

Upvotes: 0

Views: 1090

Answers (3)

The fourth bird
The fourth bird

Reputation: 163277

In your pattern ^-?\d+\.?\d+[-+*\/]-?\d+\.?\d+$ you want to match an optional dot using \d+\.?\d+ which works but now the minimum number of digits to match is 2 due to matching 2 times 1 or more digits using \d+ so 1+1 would not match.

What you could do if it are only simple calculations, you could use 3 capturing groups and match a digit with an optional decimal part using ?\d+(?:\.\d+)?

Your pattern might look like:

^(-?\d+(?:\.\d+)?)([-+*\/])(-?\d+(?:\.\d+)?)$

Explanation

  • ^ Start of string
  • (-?\d+(?:\.\d+)?) Capture group 1, match 1+ digits with an optional decimal part
  • ([-+*\/]) Capture group 2, match any of the listed in the character class
  • (-?\d+(?:\.\d+)?) Capture group 2, match 1+ digits with an optional decimal part
  • $ End of string

See the regex101 demo

For example

var regex = /^(-?\d+(?:\.\d+)?)([-+*\/])(-?\d+(?:\.\d+)?)$/;
[
  "21+22",
  "7.01+9.05",
  "1-1",
  "1*1",
  "0*1000000",
  "8/4"
].forEach(x => {
  var res = x.match(regex);
  var left = res[1];
  var right = res[2];
  var sing = res[3];
  console.log(left, right, sing);
});

Upvotes: 1

Maheer Ali
Maheer Ali

Reputation: 36564

You can do that using split()

var input = '7.01+9.05';

var pattern = /^-?\d+\.?\d+[-+*\/]-?\d+\.?\d+$/
if (input.match(pattern)) {
    var matches = pattern.exec(input)[0].split(/(\+|-|\*|\/)/);

    var left = matches[0];
    var right = matches[2];
    var sign = matches[1];
    console.log(left,sign,right);
}

Upvotes: 1

deleuterio
deleuterio

Reputation: 548

Sure!

You should define capture groups in your regex expression using () and |. It is important define a flag global to your regex to capture all groups.

There are 3 things you need to capture:

  • the left number -> ^-?\d+\.?\d+
  • the sign -> [-+*\/]
  • the right number -> -?\d+\.?\d+$

You should use | alternation to regex use the capturing groups like a or statement beetwen the groups.

The final regex will be:

var pattern = /(^-?\d+\.?\d+)|([-+*\/])|(-?\d+\.?\d+$)/g

The ouput result will be an array where the first position will be the left number, second position the sign and the third position a right number.

Therefore the rest of your code will looks like that:

if (input.match(pattern)) {
    var matches = input.match(pattern); \\ I recommend use input.match here too

    var left = matches[0];
    var right = matches[2];
    var sing = matches[1];
}

Upvotes: 1

Related Questions