Skip to content

7. Expressions régulières

Les scripts de ce chapitre se trouvent dans le dossier [regexp] du projet. En TypeScript comme en JavaScript, une expression régulière n'est pas une chaîne de caractères mais un objet à part entière, du type RegExp — on ne met donc pas de guillemets autour d'une expression régulière.

7.1. script [regexp-01]

Ce script confronte plusieurs chaînes à différents modèles (une suite de chiffres, une date jj/mm/aa, un nombre décimal), et récupère les groupes capturés :

'use strict';

/// expressions régulières en javascript
// récupérer les différents champs d'une chaîne
// le modèle : une suite de chiffres entourée de caractères quelconques
// on ne veut récupérer que la suite de chiffres
let modèle: RegExp = /(\d+)/;
console.log("type d'une expression régulière : ", typeof (modèle));
// on confronte la chaîne au modèle
compareModèleToChaîne(modèle, "xyz1234abcd");
compareModèleToChaîne(modèle, "12 34");
compareModèleToChaîne(modèle, "abcd");

// le modèle : une suite de chiffres entourée de caractères quelconques
// on veut la suite de chiffres ainsi que les champs qui suivent et précèdent
modèle = /^(.*?)(\d+)(.*?)$/;
// on confronte la chaîne au modèle
compareModèleToChaîne(modèle, "xyz1234abcd");
compareModèleToChaîne(modèle, "12 34");
compareModèleToChaîne(modèle, "abcd");

// le modèle - une date au format jj/mm/aa
modèle = /^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/;
compareModèleToChaîne(modèle, "10/05/97");
compareModèleToChaîne(modèle, "  04/04/01  ");
compareModèleToChaîne(modèle, "5/1/01");

// le modèle - un nombre décimal
modèle = /^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/;
compareModèleToChaîne(modèle, "187.8");
compareModèleToChaîne(modèle, "-0.6");
compareModèleToChaîne(modèle, "4");
compareModèleToChaîne(modèle, ".6");
compareModèleToChaîne(modèle, "4.");
compareModèleToChaîne(modèle, " + 4");

// --------------------------------------------------------------------------
function compareModèleToChaîne(modèle: RegExp, chaîne: string): void {
  // compare la chaîne [chaîne] au modèle [modèle]
  console.log(`----------- chaîne=${chaîne}, modèle=${modèle}`)
  // on confronte la chaîne au modèle
  const result1 = modèle.exec(chaîne);
  console.log(`comparaison avec exec=`, result1);
  // une autre façon de faire
  const result2 = chaîne.match(modèle);
  console.log(`comparaison avec match=`, result2);
}
  • ligne 7 : let modèle: RegExp = /(\d+)/ — le type RegExp est explicite ici, mais TypeScript l'aurait de toute façon déduit automatiquement de la syntaxe /.../ ;
  • les méthodes [modèle.exec(chaîne)] et [chaîne.match(modèle)] rendent le même résultat : soit null (pas de correspondance), soit un tableau où :
    • l'élément [0] est la chaîne entière qui correspond au modèle ;
    • les éléments [1], [2]... correspondent aux groupes capturés entre parenthèses, dans l'ordre ;
    • la propriété .index donne la position de la correspondance dans la chaîne ;
    • la propriété .input redonne la chaîne d'origine.
npx tsx regexp/regexp-01.ts

Résultat de l'exécution :

type d'une expression régulière :  object
----------- chaîne=xyz1234abcd, modèle=/(\d+)/
comparaison avec exec= [ '1234', '1234', index: 3, input: 'xyz1234abcd', groups: undefined ]
comparaison avec match= [ '1234', '1234', index: 3, input: 'xyz1234abcd', groups: undefined ]
----------- chaîne=12 34, modèle=/(\d+)/
comparaison avec exec= [ '12', '12', index: 0, input: '12 34', groups: undefined ]
comparaison avec match= [ '12', '12', index: 0, input: '12 34', groups: undefined ]
----------- chaîne=abcd, modèle=/(\d+)/
comparaison avec exec= null
comparaison avec match= null
----------- chaîne=xyz1234abcd, modèle=/^(.*?)(\d+)(.*?)$/
comparaison avec exec= [ 'xyz1234abcd', 'xyz', '1234', 'abcd', index: 0, input: 'xyz1234abcd', groups: undefined ]
comparaison avec match= [ 'xyz1234abcd', 'xyz', '1234', 'abcd', index: 0, input: 'xyz1234abcd', groups: undefined ]
----------- chaîne=12 34, modèle=/^(.*?)(\d+)(.*?)$/
comparaison avec exec= [ '12 34', '', '12', ' 34', index: 0, input: '12 34', groups: undefined ]
comparaison avec match= [ '12 34', '', '12', ' 34', index: 0, input: '12 34', groups: undefined ]
----------- chaîne=abcd, modèle=/^(.*?)(\d+)(.*?)$/
comparaison avec exec= null
comparaison avec match= null
----------- chaîne=10/05/97, modèle=/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/
comparaison avec exec= [ '10/05/97', '10', '05', '97', index: 0, input: '10/05/97', groups: undefined ]
comparaison avec match= [ '10/05/97', '10', '05', '97', index: 0, input: '10/05/97', groups: undefined ]
----------- chaîne=  04/04/01  , modèle=/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/
comparaison avec exec= [ '  04/04/01  ', '04', '04', '01', index: 0, input: '  04/04/01  ', groups: undefined ]
comparaison avec match= [ '  04/04/01  ', '04', '04', '01', index: 0, input: '  04/04/01  ', groups: undefined ]
----------- chaîne=5/1/01, modèle=/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/
comparaison avec exec= null
comparaison avec match= null
----------- chaîne=187.8, modèle=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
comparaison avec exec= [ '187.8', '', '187.8', index: 0, input: '187.8', groups: undefined ]
comparaison avec match= [ '187.8', '', '187.8', index: 0, input: '187.8', groups: undefined ]
----------- chaîne=-0.6, modèle=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
comparaison avec exec= [ '-0.6', '-', '0.6', index: 0, input: '-0.6', groups: undefined ]
comparaison avec match= [ '-0.6', '-', '0.6', index: 0, input: '-0.6', groups: undefined ]
----------- chaîne=4, modèle=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
comparaison avec exec= [ '4', '', '4', index: 0, input: '4', groups: undefined ]
comparaison avec match= [ '4', '', '4', index: 0, input: '4', groups: undefined ]
----------- chaîne=.6, modèle=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
comparaison avec exec= [ '.6', '', '.6', index: 0, input: '.6', groups: undefined ]
comparaison avec match= [ '.6', '', '.6', index: 0, input: '.6', groups: undefined ]
----------- chaîne=4., modèle=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
comparaison avec exec= [ '4.', '', '4.', index: 0, input: '4.', groups: undefined ]
comparaison avec match= [ '4.', '', '4.', index: 0, input: '4.', groups: undefined ]
----------- chaîne= + 4, modèle=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
comparaison avec exec= [ ' + 4', '+', '4', index: 0, input: ' + 4', groups: undefined ]
comparaison avec match= [ ' + 4', '+', '4', index: 0, input: ' + 4', groups: undefined ]

7.2. script [regexp-02]

Parfois, on ne souhaite pas récupérer des éléments de la chaîne testée mais seulement savoir si elle correspond au modèle. On utilise alors [RegExp.test] plutôt que exec/match, et on peut retirer les parenthèses de capture, désormais inutiles :

'use strict';

/// expressions régulières en javascript
// récupérer les différents champs d'une chaîne
// le modèle : une suite de chiffres entourée de caractères quelconques
// on ne veut récupérer que la suite de chiffres
let modèle: RegExp = /\d+/;
console.log("type d'une expression régulière : ", typeof (modèle));
// on confronte la chaîne au modèle
compareModèleToChaîne(modèle, "xyz1234abcd");
compareModèleToChaîne(modèle, "12 34");
compareModèleToChaîne(modèle, "abcd");

// le modèle : une suite de chiffres entourée de caractères quelconques
// on veut la suite de chiffres ainsi que les champs qui suivent et précèdent
modèle = /^.*?\d+.*?$/;
// on confronte la chaîne au modèle
compareModèleToChaîne(modèle, "xyz1234abcd");
compareModèleToChaîne(modèle, "12 34");
compareModèleToChaîne(modèle, "abcd");

// le modèle - une date au format jj/mm/aa
modèle = /^\s*\d\d\/\d\d\/\d\d\s*$/;
compareModèleToChaîne(modèle, "10/05/97");
compareModèleToChaîne(modèle, "  04/04/01  ");
compareModèleToChaîne(modèle, "5/1/01");

// le modèle - un nombre décimal
modèle = /^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/;
compareModèleToChaîne(modèle, "187.8");
compareModèleToChaîne(modèle, "-0.6");
compareModèleToChaîne(modèle, "4");
compareModèleToChaîne(modèle, ".6");
compareModèleToChaîne(modèle, "4.");
compareModèleToChaîne(modèle, " + 4");

// --------------------------------------------------------------------------
function compareModèleToChaîne(modèle: RegExp, chaîne: string): void {
  // test
  const correspond = modèle.test(chaîne);
  // compare la chaîne [chaîne] au modèle [modèle]
  console.log(`----------- chaîne=${chaîne}, modèle=${modèle}, correspond=${correspond}`);
}
npx tsx regexp/regexp-02.ts

Résultat de l'exécution :

type d'une expression régulière :  object
----------- chaîne=xyz1234abcd, modèle=/\d+/, correspond=true
----------- chaîne=12 34, modèle=/\d+/, correspond=true
----------- chaîne=abcd, modèle=/\d+/, correspond=false
----------- chaîne=xyz1234abcd, modèle=/^.*?\d+.*?$/, correspond=true
----------- chaîne=12 34, modèle=/^.*?\d+.*?$/, correspond=true
----------- chaîne=abcd, modèle=/^.*?\d+.*?$/, correspond=false
----------- chaîne=10/05/97, modèle=/^\s*\d\d\/\d\d\/\d\d\s*$/, correspond=true
----------- chaîne=  04/04/01  , modèle=/^\s*\d\d\/\d\d\/\d\d\s*$/, correspond=true
----------- chaîne=5/1/01, modèle=/^\s*\d\d\/\d\d\/\d\d\s*$/, correspond=false
----------- chaîne=187.8, modèle=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, correspond=true
----------- chaîne=-0.6, modèle=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, correspond=true
----------- chaîne=4, modèle=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, correspond=true
----------- chaîne=.6, modèle=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, correspond=true
----------- chaîne=4., modèle=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, correspond=true
----------- chaîne= + 4, modèle=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, correspond=true