en.javascript.info/11-regular-expressions-javascript/9-regexp-groups/2-parse-expression/solution.md
2015-03-24 00:03:51 +03:00

53 lines
2.8 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.

Регулярное выражение для числа, возможно, дробного и отрицательного: <code class="pattern">-?\d+(\.\d+)?</code>. Мы уже разбирали его в предыдущих задачах.
Оператор -- это <code class="pattern">[-+*/]</code>. Заметим, что дефис <code class="pattern">-</code> идёт в списке первым, так как на любой позиции, кроме первой и последней, он имеет специальный смысл внутри <code class="pattern">[...]</code>, и его понадобилось бы экранировать.
Кроме того, когда мы оформим это в JavaScript-синтаксис <code class="pattern">/.../</code> -- понадобится заэкранировать слэш <code class="pattern">/</code>.
Нам нужно число, затем оператор, затем число, и необязательные пробелы между ними.
Полное регулярное выражение будет таким: <code class="pattern">-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?</code>.
Чтобы получить результат в виде массива, добавим скобки вокруг тех данных, которые нам интересны, то есть -- вокруг чисел и оператора: <code class="pattern">(-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?)</code>.
Посмотрим в действии:
```js
//+ run
var re = /(-?\d+(\.\d+)?)\s*([-+*\/])\s*(-?\d+(\.\d+)?)/;
alert( "1.2 + 12".match(re) );
```
Итоговый массив будет включать в себя компоненты:
<ul>
<li>`result[0] == "1.2 + 12"` (вначале всегда полное совпадение)</li>
<li>`result[1] == "1"` (первая скобка)</li>
<li>`result[2] == "2"` (вторая скобка -- дробная часть `(\.\d+)?`)</li>
<li>`result[3] == "+"` (...)</li>
<li>`result[4] == "12"` (...)</li>
<li>`result[5] == undefined` (последняя скобка, но у второго числа дробная часть отсутствует)</li>
</ul>
Нам из этого массива нужны только числа и оператор. А, скажем, дробная часть сама по себе -- не нужна.
Уберём её из запоминания, добавив в начало скобки <code class="pattern">?:</code>, то есть: <code class="pattern">(?:\.\d+)?</code>.
Итого, решение:
```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
```