Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write regex to split two consecutive maths operators( "/-", "*-") from a string equation?

I'm trying to solve a problem where I need to convert string equation to an array of numbers and operators.But I'm unable to do it.

Regex that I wrote to convert the string equation to an array.

Input: '1+2-33/45*78'.split(/([\\+\-\\*\\/]+)/)

Output: ["1", "+", "2", "-", "33", "/", "45", "*", "78"]

But the above regex doesn't work well for when you have two operators consecutive - (*-). See below for more clarification.

Input: '1+2-33/-45*-78'.split(/([\\+\-\\*\\/]+)/)

Output: ["1", "+", "2", "-", "33", "/-", "45", "*-", "78"]

I'm expecting output like below.

Input: '1+2-33/-45*-78'

Output: ["1", "+", "2", "-", "33", "/", "-45", "*", "-78"]

Edit: I looked up all the answers here on stackOverflow but they don't solve the problem I described above.

Stackoverflow answers will solve this equation like this: This string '7/-2*-9-8' will be converted to ["7", "/-", "2", "*-", "9", "-", "8"]

Please note two consecutive operators ["/-", "*-"] above.

But this is not what I'm looking for. The output I'm expecting is like:

Expected Answer: ["7", "/", "-2", "*", "-9", "-", "8]

So If have something like this '7/-2*-9-8'. Please note that I have consecutive operators("/-" or "*-") here. Then I want to include negative sign in the number itself.

All the answers in stackoverflow doesn't solve this issue. Please reopen the question.Thanks!

Why: I'm trying to implement a simple calculator with only (+, /, -, *) operators. I hope that clears some doubt.

like image 705
Purnima Avatar asked Jul 10 '19 21:07

Purnima


1 Answers

I agree with the other users that you should not be using regex to do expression parsing, there are many libraries out there that will do a much better job of handling all of the corner cases. That being said you can certainly build a regex to handle the simple expressions outlined in your question.

First lets build a regex that captures numbers (and their sign) when they are preceded by a * or / (positive lookbehind):

(?<=[/*])([+-]?\d+)

Then we can capture the symbols:

([/*+-])

And finally capture the remaining numbers (without signs):

(\d+)

Now we can combine the various regex segments to form our simple expression parser:

(?<=[/*])([+-]?\d+)|([/*+-])|(\d+)

This solution is certainly not bulletproof, it breaks down when there are spaces and does not handle parentheses, but given the example input it works as expected.


var expression = '1+2-33/-45*-78'.match(/(?<=[/*])([+-]?\d+)|([/*+-])|(\d+)/g);
console.log(expression);
like image 184
Jake Holzinger Avatar answered Oct 23 '22 08:10

Jake Holzinger