Parse an expression
An arithmetical expression consists of 2 numbers and an operator between them, for instance:
1 + 2
1.2 * 3.4
-3 / -6
-2 - 2
The operator is one of:
There may be extra spaces at the beginning, at the end or between the parts.
Create a function
parse(expr) that takes an expression and returns an array of 3 items:
- The first number.
- The operator.
- The second number.
let [a, op, b] = parse("1.2 * 3.4"); alert(a); // 1.2 alert(op); // * alert(b); // 3.4
A regexp for a number is:
-?\d+(\.\d+)?. We created it in the previous task.
An operator is
[-+*/]. The hyphen
- goes first in the square brackets, because in the middle it would mean a character range, while we just want a character
/.../, we’ll do that later.
We need a number, an operator, and then another number. And optional spaces between them.
The full regular expression:
It has 3 parts, with
\s* between them:
-?\d+(\.\d+)?– the first number,
[-+*/]– the operator,
-?\d+(\.\d+)?– the second number.
To make each of these parts a separate element of the result array, let’s enclose them in parentheses:
The result includes:
result == "1.2 + 12"(full match)
result == "1.2"(first group
(-?\d+(\.\d+)?)– the first number, including the decimal part)
result == ".2"(second group
(\.\d+)?– the first decimal part)
result == "+"(third group
([-+*\/])– the operator)
result == "12"(forth group
(-?\d+(\.\d+)?)– the second number)
result == undefined(fifth group
(\.\d+)?– the last decimal part is absent, so it’s undefined)
We only want the numbers and the operator, without the full match or the decimal parts, so let’s “clean” the result a bit.
The full match (the arrays first item) can be removed by shifting the array
Groups that contain decimal parts (number 2 and 4)
(.\d+) can be excluded by adding
?: to the beginning:
The final solution:
As an alternative to using the non-capturing
?:, we could name the groups, like this: