53 lines
2.8 KiB
Markdown
53 lines
2.8 KiB
Markdown
Регулярное выражение для числа, возможно, дробного и отрицательного: <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
|
||
```
|
||
|