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 fr.javascript.info — Parsez une expression

  • Tutoriel
  • Expressions régulières
  • Groupes capturant
retour au cours

Parsez une expression

Une expression arithmétique consiste en 2 nombres et un opérateur entre les deux, par exemple :

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

L’opérateur l’un des : "+", "-", "*" ou "/".

Il peut y avoir des espaces supplémentaires au début, à la fin ou entre chaque partie.

Créez une fonction parse(expr) qui prend une expression et retourne un tableau de trois éléments :

  1. Le premier nombre.
  2. L’opérateur.
  3. Le second nombre.

Par exemple :

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

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

Une regexp pour un nombre : -?\d+(\.\d+)?. Nous l’avons vu dans l’exercice précédent.

Pour l’opérateur [-+*/]. Le tiret - est en premier, car il pourrait signifier un intervalle de caractère, alors que nous souhaitons juste le caractère -.

Le slash / doit être échappé en javascript dans une regexp /.../, et nous le ferons plus tard.

Nous cherchons un nombre, un opérateur puis un autre nombre. Et d’éventuels espaces entre eux.

Cela done l’expression régulière : -?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?.

Il y a trois parties, avec \s* entre elles :

  1. -?\d+(\.\d+)? – le premier nombre,
  2. [-+*/] – l’opérateur,
  3. -?\d+(\.\d+)? – le deuxième nombre.

Pour faire de chacune de ces parties un élément distinct du tableau de correspondance, entourons-les de parenthèses : (-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?).

Cela donne :

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

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

Le résultat inclus :

  • result[0] == "1.2 + 12" (la correspondance complète)
  • result[1] == "1.2" (premier groupe (-?\d+(\.\d+)?) – le premier nombre, avec la partie décimale)
  • result[2] == ".2" (second groupe(\.\d+)? – la première partie décimale)
  • result[3] == "+" (troisième groupe ([-+*\/]) – l’opérateur)
  • result[4] == "12" (quatrième groupe (-?\d+(\.\d+)?) – le second nombre)
  • result[5] == undefined (cinquième groupe (\.\d+)? – la deuxième partie décimale est absente, c’est non défini)

Nous ne souhaitons que les nombres et l’opérateur, sans la correspondance entière, ni les parties décimales. Faisons alors un peu le ménage.

La correspondance complète(le premier élément du tableau) peut être enlevée par result.shift().

Les groupes contenant les parties décimales(groupes 2 et 4) (.\d+) peuvent être exclus en ajoutant ?: au début : (?:\.\d+)?.

La solution complète :

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.