14 mai 2024

Quantificateurs +, *, ? et {n}

Considérons que nous avons une chaßne de caractÚres +7(903)-123-45-67 et que nous voulons trouver tous les nombres dedans. Mais contrairement à avant nous ne voulons pas seulement trouver les chiffres mais les nombres en entier: 7, 903, 123, 45, 67.

Un nombre est une séquence de 1 ou plus chiffres \d. Pour marquer la quantité dont nous avons besoin, nous pouvons ajouter un quantificateur.

Quantité {n}

Le quantificateur le plus simple est un nombre entre accolades: {n}.

Un quantificateur est attaché à un caractÚre (ou une classe de caractÚre, ou un jeu [...], etc) et spécifie la quantité dont nous avons besoin.

Il a quelques formes avancées, comme par exemple:

Le nombre exact: {5}

\d{5} indique exactement 5 chiffres, identique Ă  \d\d\d\d\d.

L’exemple ci-dessous recherche un nombre à 5 chiffres:

alert( "I'm 12345 years old".match(/\d{5}/) ); //  "12345"

Nous pouvons ajouter \b pour exclure les nombres plus longs: \b\d{5}\b.

La portée: {3,5}, correspond de 3 à 5 fois

Pour trouver les nombres avec de 3 Ă  5 chiffres nous pouvons mettre les limites entre accolades: \d{3,5}

alert( "I'm not 12, but 1234 years old".match(/\d{3,5}/) ); // "1234"

Nous pouvons retirer la limite haute.

Une regexp \d{3,} cherche donc une sĂ©quence de chiffres d’une longueur de 3 ou plus:

alert( "I'm not 12, but 345678 years old".match(/\d{3,}/) ); // "345678"

Retournons Ă  la chaĂźne de caractĂšres +7(903)-123-45-67.

Un nombre est une séquence de un ou plus chiffres à la suite. Donc la regexp est \d{1,}:

let str = "+7(903)-123-45-67";

let numbers = str.match(/\d{1,}/g);

alert(numbers); // 7,903,123,45,67

Abréviations

Il y a des abréviations pour les quantificateur les plus utilisés:

+

Signifie “un ou plus”, identique à {1,}.

Par exemple, \d+ cherche les nombres:

let str = "+7(903)-123-45-67";

alert( str.match(/\d+/g) ); // 7,903,123,45,67
?

Signifie “zĂ©ro ou un”, identique Ă  {0,1}. En d’autres termes, il rend le symbole optionnel.

Par exemple, le pattern ou?r cherche o suivi de zéro ou un u, puis r.

Donc, colou?r trouve color et colour:

let str = "Should I write color or colour?";

alert( str.match(/colou?r/g) ); // color, colour
*

Signifie “zĂ©ro ou plus”, identique Ă  {0,}. C’est-Ă -dire que le caractĂšre peut ĂȘtre rĂ©pĂ©tĂ© n’importe quel nombre de fois ou bien ĂȘtre absent.

Par exemple, \d0* cherche un chiffre suivi de n’importe quel nombre de zĂ©ros (plusieurs ou aucun):

alert( "100 10 1".match(/\d0*/g) ); // 100, 10, 1

Comparé à + (un ou plus):

alert( "100 10 1".match(/\d0+/g) ); // 100, 10
// 1 n'est pas trouvé, puisque 0+ nécessite au moins un zéro

Plus d’exemples

Les quantificateurs sont utilisĂ©s trĂšs souvent. Ils servent de “bloc de construction” principal pour les expressions rĂ©guliĂšres complexes, regardons d’autres exemples.

Regexp pour fractions décimales (un nombre à virgule flotante): \d+\.\d+

En action:

alert( "0 1 12.345 7890".match(/\d+\.\d+/g) ); // 12.345

Regexp pour une “balise HTML d’ouverture sans attributs”, comme <span> ou <p>.

  1. La plus simple: /<[a-z]+>/i

    alert( "<body> ... </body>".match(/<[a-z]+>/gi) ); // <body>

    Cette regexp cherche le caractĂšre '<' suivi par une ou plusieurs lettres Latin, puis '>'.

  2. Amélioré: /<[a-z][a-z0-9]*>/i

    ConformĂ©ment au standard, Le nom d’une balise HTML peut avoir un chiffre Ă  n’importe quel endroit Ă  l’exception de la premiĂšre position, comme <h1>.

    alert( "<h1>Hi!</h1>".match(/<[a-z][a-z0-9]*>/gi) ); // <h1>

Regexp “balise HTML d’ouverture ou de fermeture sans attributs”: /<\/?[a-z][a-z0-9]*>/i

Nous avons ajoutĂ© un slash optionnel /? prĂšs du dĂ©but du pattern. Nous avons dĂ» l’échapper avec un backslash, sinon JavaScript aurait pensĂ© que c’était la fin du pattern.

alert( "<h1>Hi!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) ); // <h1>, </h1>
Pour rendre une regexp plus précise, nous devons souvent la rendre plus complexe

Vous pouvez voir une rĂšgle commune dans tous ces exemples: plus une expression rĂ©guliĂšre est prĂ©cise – plus elle est longue et complexe.

Par exemple, pour des balises HTML nous pourrions utiliser une regexp plus simple: <\w+>. Mais comme HTML a des restrictions plus strictes pour les noms de balise, <[a-z][a-z0-9]*> est plus fiable.

Pouvons nous utiliser <\w+> ou avons nous besoin de <[a-z][a-z0-9]*>?

Dans la vrai vie les deux variantes sont acceptables. En fonction de la tolĂ©rance que nous avons vis-Ă -vis des sĂ©lections “en trop” et la difficultĂ© que l’on a de les retirer des rĂ©sultats par d’autres moyens.

Exercices

importance: 5

Créer une regexp pour trouver une ellipse: 3 (ou plus?) points à la suite.

Vérifiez:

let regexp = /votre regexp/g;
alert( "Hello!... How goes?.....".match(regexp) ); // ..., .....

Solution:

let regexp = /\.{3,}/g;
alert( "Hello!... How goes?.....".match(regexp) ); // ..., .....

Notez que le point est un caractĂšre spĂ©cial, nous devons donc l’échapper et l’insĂ©rer comme ceci \..

CrĂ©ez une regexp pour trouver les couleurs HTML Ă©crites comme #ABCDEF: d’abord # puis 6 caractĂšres hexadĂ©cimaux.

Exemple d’utilisation:

let regexp = /...votre regexp.../

let str = "color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2 #12345678";

alert( str.match(regexp) )  // #121212,#AA00ef

P.S. Dans cette tñche nous n’avons pas besoin des autres formats de couleur comme #123 ou rgb(1,2,3) etc.

Nous devons chercher # suivi de 6 caractÚres hexadécimaux.

Un caractÚre hexadécimal est défini comme [0-9a-fA-F]. Ou si nous utilisons le flag i, juste [0-9a-f].

Nous pouvons ensuite rechercher 6 d’entre eux en utilisant le quantificateur {6}.

Résultat, nous avons la regexp: /#[a-f0-9]{6}/gi.

let regexp = /#[a-f0-9]{6}/gi;

let str = "color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2"

alert( str.match(regexp) );  // #121212,#AA00ef

Le problĂšme est qu’elle trouve la couleur dans des sĂ©quences plus longues:

alert( "#12345678".match( /#[a-f0-9]{6}/gi ) ) // #123456

Pour rĂšgler ceci nous pouvons ajouter \b Ă  la fin:

// color
alert( "#123456".match( /#[a-f0-9]{6}\b/gi ) ); // #123456

// not a color
alert( "#12345678".match( /#[a-f0-9]{6}\b/gi ) ); // null
Carte du tutoriel

Commentaires

lire ceci avant de commenter

  • Si vous avez des amĂ©liorations Ă  suggĂ©rer, merci de soumettre une issue GitHub ou une pull request au lieu de commenter.
  • Si vous ne comprenez pas quelque chose dans l'article, merci de prĂ©ciser.
  • Pour insĂ©rer quelques bouts de code, utilisez la balise <code>, pour plusieurs lignes – enveloppez-les avec la balise <pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepen
)