diff --git a/10-regular-expressions-javascript/09-regexp-groups/2-parse-expression/solution.md b/10-regular-expressions-javascript/09-regexp-groups/2-parse-expression/solution.md deleted file mode 100644 index d224acdc..00000000 --- a/10-regular-expressions-javascript/09-regexp-groups/2-parse-expression/solution.md +++ /dev/null @@ -1,49 +0,0 @@ -Регулярное выражение для числа, возможно, дробного и отрицательного: `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 -``` - diff --git a/10-regular-expressions-javascript/09-regexp-groups/2-parse-expression/task.md b/10-regular-expressions-javascript/09-regexp-groups/2-parse-expression/task.md deleted file mode 100644 index 56ad74bb..00000000 --- a/10-regular-expressions-javascript/09-regexp-groups/2-parse-expression/task.md +++ /dev/null @@ -1,19 +0,0 @@ -# Разобрать выражение - -Арифметическое выражение состоит из двух чисел и операции между ними, например: - -- `1 + 2` -- `1.2 * 3.4` -- `-3 / -6` -- `-2 - 2` - -Список операций: `"+"`, `"-"`, `"*"` и `"/"`. - -Также могут присутствовать пробелы вокруг оператора и чисел. - -Напишите функцию, которая будет получать выражение и возвращать массив из трёх аргументов: - -1. Первое число. -2. Оператор. -3. Второе число. - diff --git a/10-regular-expressions-javascript/09-regexp-groups/5-parse-expression/solution.md b/10-regular-expressions-javascript/09-regexp-groups/5-parse-expression/solution.md new file mode 100644 index 00000000..08d4843e --- /dev/null +++ b/10-regular-expressions-javascript/09-regexp-groups/5-parse-expression/solution.md @@ -0,0 +1,49 @@ +A regexp for a number is: `pattern:-?\d+(\.\d+)?`. We created it in previous tasks. + +An operator is `pattern:[-+*/]`. We put a dash `pattern:-` the first, because in the middle it would mean a character range, we don't need that. + +Note that a slash should be escaped inside a JavaScript regexp `pattern:/.../`. + +We need a number, an operator, and then another number. And optional spaces between them. + +The full regular expression: `pattern:-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?`. + +To get a result as an array let's put parentheses around the data that we need: numbers and the operator: `pattern:(-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?)`. + +In action: + +```js run +let reg = /(-?\d+(\.\d+)?)\s*([-+*\/])\s*(-?\d+(\.\d+)?)/; + +alert( "1.2 + 12".match(reg) ); +``` + +The result includes: + +- `result[0] == "1.2 + 12"` (full match) +- `result[1] == "1"` (first parentheses) +- `result[2] == "2"` (second parentheses -- the decimal part `(\.\d+)?`) +- `result[3] == "+"` (...) +- `result[4] == "12"` (...) +- `result[5] == undefined` (the last decimal part is absent, so it's undefined) + +We need only numbers and the operator. We don't need decimal parts. + +So let's remove extra groups from capturing by added `pattern:?:`, for instance: `pattern:(?:\.\d+)?`. + +The final solution: + +```js run +function parse(expr) { + let reg = /(-?\d+(?:\.\d+)?)\s*([-+*\/])\s*(-?\d+(?:\.\d+)?)/; + + let result = expr.match(reg); + + if (!result) return; + result.shift(); + + return result; +} + +alert( parse("-1.23 * 3.45") ); // -1.23, *, 3.45 +``` diff --git a/10-regular-expressions-javascript/09-regexp-groups/5-parse-expression/task.md b/10-regular-expressions-javascript/09-regexp-groups/5-parse-expression/task.md new file mode 100644 index 00000000..8b54d468 --- /dev/null +++ b/10-regular-expressions-javascript/09-regexp-groups/5-parse-expression/task.md @@ -0,0 +1,28 @@ +# 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: `"+"`, `"-"`, `"*"` or `"/"`. + +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: + +1. The first number. +2. The operator. +3. The second number. + +For example: + +```js +let [a, op, b] = parse("1.2 * 3.4"); + +alert(a); // 1.2 +alert(op); // * +alert(b); // 3.4 +```