Aller au contenu

TD : Les Regex en Javascript⚓︎

Créer une regex en JS⚓︎

var s = "hello" // est considéré comme une string, et non pas une regex, à cause des guillements
var r = /hello/ // est considéré comme une regex grâce aux deux slashs extrémaux
new String ("hello") // est la syntaxe pour définir une chaîne
new RegExp ("ab[0-5]") // est la syntaxe pour définir la regex 'ab[0-5]' via à RgExp()

Quelques Méthodes/Propriétés des Regex en JS⚓︎

Dans toute la suite :

  • r désigne une regex
  • s (s1, etc..) désigne une string
  • f désigne une fonction

r.test(s)⚓︎

La méthode r.test(s) renvoie un booléen :

  • true lorsque la regex r matche la chaîne s (au moins une occurence)
  • false sinon (aucune occurence)
let r = /\d{3}/
r.test("hello");    // renvoie false
r.test("456");      // renvoie true
r.test("456ABC");   // renvoie true

Exo

  1. Créer une regex pour tester un email (de domaines .net, .com ou .org) avec la méthode .test()

s.match()⚓︎

La méthode s.match(r) renvoie un array / tableau contenant les occurences pour lesquelles la chaîne s match la regex r.

let s = "des fraises, des kiwis et des mangues"
s.match(/fraises/);  // renvoie ["fraises"]
s.match(/\w+/);  // renvoie SEULEMENT ["des"], pourquoi pas TOUS les mots ??

⚠ Sauf mention contraire, cette méthode renvoie seulement le premier match de la chaîne s avec la regex. Pour résoudre cela, on utilise des :

Flags⚓︎

Les flags modifient le comportement des regex :

Flag Signification
g Global :
renvoyer non seulement le premier match
mais la globalité d'entre eux (tous)
i Insensible à la casse :
renvoyer le premier match
de manière Insensible à la casse
  • Lorsque la regex est globale /g, alors s.match(r) renvoie l'ensemble de tous les matches, mais sans les groupes
  • Au contraire, Lorsque la regex n'est PAS globale (pas de /g), alors s.match(r) renvoie seulement le premier match, mais avec les groupes
let s = "des fraises, des kiwis et des mangues";
s.match(/\b\w+\b/);  // renvoie SEULEMENT [ "des" ]
s.match(/\b\w+\b/g);  // renvoie [ "des", "fraises", "des", "kiwis", "et", "des", "mangues" ]

Groupes⚓︎

Le Flag /g empêche la création des groupes :

let s = "111-2222 est un numéro et 333-444 en est un autre";
s.match(/(\d{3})[-.]\d{4}/g);  // renvoie ["111-2222", "333-4444"] Où sont les groupes de 3 chiffres ? Absents...

Mais sans les flags, on peut retrouver les groupes :

let s = "111-2222 est un numéro et 333-444 en est un autre";
s.match(/(\d{3})[-.]\d{4}/);  // renvoie ["111-2222", "111"] donc : group[0], puis group[1]

r.exec(s)⚓︎

Il est néanmoins possible d'utiliser simultanément le flag /g ET les groupes : il faut pour cela utiliser la méthode r.exec(s).

La méthode r.exec(s) est plus ou moins équivalente à s.match(r), mais chaque nouvel appel à r.exec(s) renvoie une nouvelle occurence du match de la regex r sur la chaîne/string s, AVEC LES GROUPES (donc compatible avec le flag /g). Une boucle permet donc de récupérer toutes les occurences des match AVEC LES GROUPES.

let r = /(\d{3})[-.]\d{4}/
let s = "111-2222 est un numéro et 333-444 en est un autre";
r.exec(s);  // renvoie ["111-2222", "111"] lors de la première exécution
r.exec(s);  // renvoie ["333-444", "333"] lors de la deuxième exécution
r.exec(s);  // renvoie null lors de la troisième exécution

Exemple de boucle:

let r = /(\d{3})[-.]\d{4}/
let s = "111-2222 est un numéro et 333-444 en est un autre";
result = r.exec(s);
while (result != null) {
    result = r.exec(s);
}

s.split(r)⚓︎

let r = /\s/;
let s0 = "des fraises des kiwis et des mangues";
let s1 = "des fraises, des kiwis et des mangues";
s0.split(r); // renvoie ["des", "fraises", "des", "kiwis", "et", "des", "mangues"]
s1.split(r); // renvoie ["des", "fraises,", "des", "kiwis", "et", "des", "mangues"]

// Comment faire pour séparer/splitter par une virgule OU BIEN ou espace ?
let r = /,\s/;
s1.split(r); // renvoie [ "des fraises", "des kiwis et des mangues" ] --> pas bon
// pour splitter par un espace OU BIEN une virgule :
let r = /[,\s]/;    // ou bien : r = /[,\s]+/;
let s = "des fraises, des kiwis et des mangues";
s.split(r); // renvoie ["des", "fraises", "des", "kiwis", "et", "des", "mangues"]

s.replace(r,s0) ou s.replace(r,f)⚓︎

  • La méthode s.replace(r, s0) recherche les match de la regex r dans s, et remplace chacun d'entre eux par la chaîne/string s0. Une sorte de fonctionnalité (usuelle) Rechercher / Remplacer.
  • La méthode s.replace(r, s0) recherche les match de la regex r dans s, et exécute pour chaun d'entre eux, la fonction f (callback)

s.replace(r,s0)⚓︎

Exp

let r = /kiwis/;
let s = "des fraises, des kiwis et des mangues";
let s = "pommes";
s.replace(r, s0);   // renvoie "des fraises, des pommes et des mangues", mais réponse PAS PLACÉE dans s

⚠ Cette méthode ne remplace PAS s.
Si vous souhaitez également remplacer s par sa nouvelle valeur, il faut rédigier :

s = s.replace(r, s0);   // renvoie "des fraises, des pommes et des mangues", AVEC réponse dans s

Exp

let r = /kiwis/;
let s = "des fraises, des kiwis et des mangues";
s.replace(/\w{4,5}/, "mandarines");   // renvoie "des mandarineses, des kiwis et des mangues", mais réponse PAS PLACÉE dans s
s.replace(/\b\w{4,5}\b/g, "mandarines");   // renvoie "des fraises, des mandarines et des mangues", mais réponse PAS PLACÉE dans s

Groupes Capturés

let r = /kiwis/;
let s = "des fraises, des kiwis et des mangues";
s.replace(/[ai]/g, "$1$1");   // renvoie "des fraaises, des maandaariines et des maangues"

s.replace(r,f)⚓︎

Exp

let r = /\b\w+\b/g;
let s = "des fraises, des kiwis et des mangues";
const f = (match) => {
    console.log(match);
}
s.replace(r, f);   // exécute la fonction `f` pour chaque occurence d'un match, en lui transmettant un paramètre `match`

Ici, on obtient la sortie suivante en console :

des
fraises
des
kiwis
et
des
mangues

Exp

let r = /\b\w+\b/g;
let s = "des fraises, des kiwis et des mangues";
const f = (match) => {
    console.log(match);
    return "poires"
}
s.replace(r, f);   // exécute la fonction `f` pour chaque occurence d'un match, en lui transmettant un paramètre `match`
// Remplace chaque match par `poires`

Ici, on obtient la nouvelle chaîne suivante (dans un navigateur, pas avec node) :

"poires poires, poires poires poires poires poires"

Exp

let r = /\b\w+\b/g;
let s = "des fraises, des kiwis et des mangues";
const f = (match) => {
    console.log(match);
    if (match.length == 3) {
        return match.toUpperCase();
    } else {
        return match
    }
}
s.replace(r, f);   // exécute la fonction `f` pour chaque occurence d'un match, en lui transmettant un paramètre `match`
// Remplace les mots minuscules de 3 lettres par leurs conversions en MAJUSCULES, mais pas les autres mots.