بازگشت به درس
این محتوا تنها در این زبان‌ها موجود است: عربي, English, Español, Français, Indonesia, Italiano, 日本語, 한국어, Русский, Türkçe, Українська, 简体中文. لطفاً به ما

## Parse an expression

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 `-`.

The slash `/` should be escaped inside a JavaScript regexp `/.../`, we’ll do that later.

We need a number, an operator, and then another number. And optional spaces between them.

The full regular expression: `-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?`.

It has 3 parts, with `\s*` between them:

1. `-?\d+(\.\d+)?` – the first number,
2. `[-+*/]` – the operator,
3. `-?\d+(\.\d+)?` – the second number.

To make each of these parts a separate element of the result array, let’s enclose them in parentheses: `(-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?)`.

In action:

``````let regexp = /(-?\d+(\.\d+)?)\s*([-+*\/])\s*(-?\d+(\.\d+)?)/;

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 `result.shift()`.

Groups that contain decimal parts (number 2 and 4) `(.\d+)` can be excluded by adding `?:` to the beginning: `(?:\.\d+)?`.

The final solution:

``````function parse(expr) {
let regexp = /(-?\d+(?:\.\d+)?)\s*([-+*\/])\s*(-?\d+(?:\.\d+)?)/;

let result = expr.match(regexp);

if (!result) return [];
result.shift();

return result;
}

alert( parse("-1.23 * 3.45") );  // -1.23, *, 3.45``````

As an alternative to using the non-capturing `?:`, we could name the groups, like this:

``````function parse(expr) {
let regexp = /(?<a>-?\d+(?:\.\d+)?)\s*(?<operator>[-+*\/])\s*(?<b>-?\d+(?:\.\d+)?)/;

let result = expr.match(regexp);

return [result.groups.a, result.groups.operator, result.groups.b];
}

alert( parse("-1.23 * 3.45") );  // -1.23, *, 3.45;``````