First of all, there are lots and lots of questions about regex on math expressions, if i overlooked one that already answers this, sorry. While this stems from parsing a math expression (no eval...), it is more about "can't this be done with a single tricky regex or similar?".
Is there a way to split a string containing a math expression like "-5.42+2--3*-5.5/-2+-4" to ["-5.42", "+", "2", "-", "-3", "*", "-5.5", "/", "-2", "+", "-4"] in a single .split[1]? Else said, split binary operators (/[+*/]|(?<!^|[+\-*/])-/, that lookbehind is the issue) and their arguments (/-?\d+(\.\d+)?/). Unary minus appears at most once per number, aka no ---. There are no braces at this step.
The way i see it, without lookbehind, it is impossible to differentiate the unary - from the binary - with the restraints of split (expected answer). However, maybe there is a trick to get the same result without lookbehind. I got surprised by tricky regex workarounds too often to trust my intuition.
With several operations, here is one way of many ways (note that the first regex replace somewhat emulates a lookbehind):
console.log("-5.42+2--3*-5.5/-2+-4"
.replace(/^-|([+\-*/])-/g, "$1#")
.split(/([+\-*/])/)
.map(e => e.replace("#", "-"))
);
Another alternative would be to reverse the string, then use lookahead instead and reverse the results again.
[1] I would add (or operation) here but the question of what an "operation" is would immediately arise and completely derail the topic. Similarly would (or in a beautiful way) as being opinion based. However, i thought e.g. about using repeated parenthesized matches which is not possible in javascript but would be very similar to split.
Short answer:
You can't do what you want with just Regex. You have to use Parsing expression grammar (PEG)
Long answer
From what you're seeing, a math expression just contains terms and operators.
But in fact, it is more complex than that. Because a combination of a term and a particular operator will have higher priority than the others.
So what we have to concern are not only term and operator, but something like:
a term = a number or an expressionan unary = positive value or negative value of a terma multiple = an unary [multiply or divide to another unary]{0 times or more}a sum = a multiple [add or subtract to another multiple]{0 times or more}an expression = a sumThis is the declaration for a + - * / only expression. A more complex expression which contains parenthese, and operator, or operator etc will have more complex declaration. And you have no choice but using PEG.
So, try the PEGjs here. It has a demo of how simple expressions like "2 * (3 + 4)" are implemented.
And sure you can extract anything you want from a expression.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With