6

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.

Purnima
  • 129
  • 7
  • Can you explain why you're trying to implement this, instead of using someone else's code for this task so you can get on with writing the thing you actually wanted to write? – Mike 'Pomax' Kamermans Jul 10 '19 at 21:09
  • When regex is your hammer everything looks like a thumb. Unless you're *explicitly* tasked with using regex for this (e.g., a classroom exercise) then use an expression parser instead. A trivial one is quite simple to implement even if there weren't already libraries to do it. – Dave Newton Jul 10 '19 at 21:11
  • Also note that a simplistic approach will likely break standard mathematic precedence: you need an expression *tree* to do math correctly (or at least as most people would expect... except you Smalltalkers out there). – Dave Newton Jul 10 '19 at 21:17
  • Please explain _how_ the duplicate doesn't answer your question. Just saying it doesn't won't get you any reopen votes. – jhpratt Jul 11 '19 at 06:42
  • @jhpratt I did explain _how_ it's different. I've edited my question again. Let me know if that make sense. – Purnima Jul 11 '19 at 07:13

2 Answers2

2

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);
Jake Holzinger
  • 5,783
  • 2
  • 19
  • 33
  • Can you please provide a working example? Because this regex doesn't seem to work when I used the above regex inside `split()` – Purnima Jul 14 '19 at 11:25
  • 1
    You should use `String.prototype.match` instead of `String.prototype.split`. I edited the answer. – Jake Holzinger Jul 14 '19 at 21:46
  • Note that lookbehinds are [not yet well-supported](https://caniuse.com/#feat=js-regexp-lookbehind). – AuxTaco Jul 14 '19 at 22:56
-2

What you're looking for is the regex:

/([\+\-\*\/]{1})/

{1} at the end makes sure that only a single character is matched

Pranav Nachnekar
  • 115
  • 1
  • 10
  • Even if this worked, you wouldn't need the `{1}`, because the default quantifier is already `1`; `/([\+\-\*\/])/` would have identical behavior. That said, this won't solve the OP's problem anyway. They want the second operator (basically always a `-`) to be paired with the following number to make `'1+2-33/-45*-78'` into `["1", "+", "2", "-", "33", "/", "-45", "*", "-78"]`. Instead, they'll get `["1", "+", "2", "-", "33", "/", "", "-", "45", "*", "", "-", "78"]`, adding empty strings and separated minus signs. – ShadowRanger Jul 11 '19 at 18:07