GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

No menu could be recovered. Follow the blue links in the page.

This view

  • Original page
  • New address

GeezerVison is showing uk.javascript.info — Розберіть вираз

  • Підручник
  • Регулярні вирази
  • Групи захоплення
назад до уроку

Розберіть вираз

Арифметичний вираз складається з двох чисел та оператору між ними, наприклад:

  • 1 + 2
  • 1.2 * 3.4
  • -3 / -6
  • -2 - 2

Оператором може бути: "+", "-", "*" або "/".

Додаткові пробіли можуть бути на початку, в кінці чи всередині виразу.

Напишіть функцію parse(expr), яка приймає вираз та повертає масив з 3-ьох елементів:

  1. Перше число.
  2. Оператор.
  3. Друге число.

Наприклад:

let [a, op, b] = parse("1.2 * 3.4");

alert(a); // 1.2
alert(op); // *
alert(b); // 3.4

Регулярний вираз для числа є наступним: -?\d+(\.\d+)?. Його ми створили в рамках попередньої задачі.

Оператором слугуватиме [-+*/]. Дефіс - стоїть першим в квадратних дужках, бо позиція посередині означає діапазон знаків, тоді як нам потрібен лише -.

Символ / має бути екранованим всередині регулярного виразу JavaScript /.../, зробимо це потім.

Нам потрібне число, оператор, тоді ще одне число. Та можливі пробіли між ними.

Повний регулярний вираз: -?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?.

Він містить 3 частини, з \s* між ними:

  1. -?\d+(\.\d+)? – перше число,
  2. [-+*/] – оператор,
  3. -?\d+(\.\d+)? – друге число.

Аби зробити кожну з цих частин окремим елементом масиву результатів, помістимо їх в круглі дужки: (-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?).

Код у дії:

let regexp = /(-?\d+(\.\d+)?)\s*([-+*\/])\s*(-?\d+(\.\d+)?)/;

alert( "1.2 + 12".match(regexp) );

Розглянемо результат:

  • 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 та 5, що містять десяткові частини (.\d+), можна оминути, додавши ?: на початку: (?:\.\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

As an alternative to using the non-capturing ?:, we could name the groups, like this:

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;
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.