en.javascript.info/9-regular-expressions/09-regexp-groups/5-parse-expression/solution.md
Ilya Kantor 4f2a90854d fixes
2019-06-25 16:25:50 +03:00

1.9 KiB

A regexp for a number is: pattern:-?\d+(\.\d+)?. We created it in previous tasks.

An operator is pattern:[-+*/].

Please note:

  • Here the dash pattern:- goes first in the brackets, because in the middle it would mean a character range, while we just want a character -.
  • A slash / should be escaped inside a JavaScript regexp pattern:/.../, we'll do that later.

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:

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.2" (first group (-?\d+(\.\d+)?) -- the first number, including the decimal part)
  • result[2] == ".2" (second group(\.\d+)? -- the first decimal part)
  • result[3] == "+" (third group ([-+*\/]) -- the operator)
  • result[4] == "12" (forth group (-?\d+(\.\d+)?) -- the second number)
  • result[5] == undefined (fifth group (\.\d+)? -- the last decimal part is absent, so it's undefined)

We only want the numbers and the operator, without the full match or the decimal parts.

The full match (the arrays first item) can be removed by shifting the array pattern:result.shift().

The decimal groups can be removed by making them into non-capturing groups, by adding pattern:?: to the beginning: pattern:(?:\.\d+)?.

The final solution:

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