en.javascript.info/10-regular-expressions-javascript/08-regexp-groups/2-parse-expression/solution.md
Ilya Kantor e2443e8de6 ok
2017-03-19 16:59:53 +03:00

49 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Регулярное выражение для числа, возможно, дробного и отрицательного: `pattern:-?\d+(\.\d+)?`. Мы уже разбирали его в предыдущих задачах.
Оператор -- это `pattern:[-+*/]`. Заметим, что дефис `pattern:-` идёт в списке первым, так как на любой позиции, кроме первой и последней, он имеет специальный смысл внутри `pattern:[...]`, и его понадобилось бы экранировать.
Кроме того, когда мы оформим это в JavaScript-синтаксис `pattern:/.../` -- понадобится заэкранировать слэш `pattern:/`.
Нам нужно число, затем оператор, затем число, и необязательные пробелы между ними.
Полное регулярное выражение будет таким: `pattern:-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?`.
Чтобы получить результат в виде массива, добавим скобки вокруг тех данных, которые нам интересны, то есть -- вокруг чисел и оператора: `pattern:(-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?)`.
Посмотрим в действии:
```js run
var re = /(-?\d+(\.\d+)?)\s*([-+*\/])\s*(-?\d+(\.\d+)?)/;
alert( "1.2 + 12".match(re) );
```
Итоговый массив будет включать в себя компоненты:
- `result[0] == "1.2 + 12"` (вначале всегда полное совпадение)
- `result[1] == "1"` (первая скобка)
- `result[2] == "2"` (вторая скобка -- дробная часть `(\.\d+)?`)
- `result[3] == "+"` (...)
- `result[4] == "12"` (...)
- `result[5] == undefined` (последняя скобка, но у второго числа дробная часть отсутствует)
Нам из этого массива нужны только числа и оператор. А, скажем, дробная часть сама по себе -- не нужна.
Уберём её из запоминания, добавив в начало скобки `pattern:?:`, то есть: `pattern:(?:\.\d+)?`.
Итого, решение:
```js run
function parse(expr) {
var re = /(-?\d+(?:\.\d+)?)\s*([-+*\/])\s*(-?\d+(?:\.\d+)?)/;
var result = expr.match(re);
if (!result) return;
result.shift();
return result;
}
alert( parse("-1.23 * 3.45") ); // -1.23, *, 3.45
```