Регулярное выражение для числа: pattern:-?\d+(\.\d+)?. Мы создали его в предыдущей задаче.
Регулярное выражение для оператора pattern:[-+*/]. Дефис pattern:- стоит в начале квадратных скобок, потому что в середине этот символ будет означать диапазон, а нам нужен просто символ -.
Отметим, что косая черта должна быть экранирована внутри регулярного выражения JavaScript pattern:/.../, мы сделаем это позже.
Нам необходимо число, оператор и затем другое число. Между ними могут быть необязательные пробелы.
Полное выражение: pattern:-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?.
Оно состоит из трёх частей, между которыми стоит pattern:\s*:
pattern:-?\d+(\.\d+)?- первое число,pattern:[-+*/]- оператор,pattern:-?\d+(\.\d+)?- второе число.
Для получения этих частей в виде отдельных элементов массива-результата давайте вставим скобки вокруг каждой из них, получится pattern:(-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?).
В действии:
let regexp = /(-?\d+(\.\d+)?)\s*([-+*\/])\s*(-?\d+(\.\d+)?)/;
alert( "1.2 + 12".match(regexp) );Результат result включает в себя:
result[0] == "1.2 + 12"(полное совпадение)result[1] == "1.2"(первая группа(-?\d+(\.\d+)?)-- первое число, включая десятичную часть)result[2] == ".2"(вторая группа(\.\d+)?-- первая десятичная часть)result[3] == "+"(третья группа([-+*\/])-- оператор)result[4] == "12"(четвёртая группа(-?\d+(\.\d+)?)-- второе число)result[5] == undefined(пятая группа(\.\d+)?-- вторая десятичная часть отсутствует, поэтому значениеundefined)
Нам необходимы только числа и оператор без полного совпадения или десятичной части, поэтому давайте "почистим" этот результат.
Первый элемент массива (полное совпадение) можно удалить при помощи сдвига массива result.shift().
Группы, которые содержат десятичную часть (номер 2 и 4) pattern:(.\d+) можно убрать из массива, добавив pattern:?: в начало: pattern:(?:\.\d+)?.
Итоговое решение:
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В качестве альтернативы исключению из запоминания pattern:?: мы могли бы использовать именованные группы следующим образом:
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;