2 janvier 2021

Classes de caractères

Considérons un exemple pratique – nous avons un numero de téléphone tel que "+7(903)-123-45-67", et nous souhaitons le convertir en nombres purs : 79031234567.

Pour ce faire, nous pouvons rechercher et supprimer tout ce qui n’est pas un nombre. Les classes de caractères peuvent nous aider.

Une classe de caractères est une notation spéciale qui correspond à n’importe quel symbole d’un certain ensemble.

Pour commencer, explorons la classe “digit”. Elle s’écrit comme \d et correspond à “n’importe quel chiffre”.

Par exemple, recherchons le premier chiffre dans le numéro de téléphone :

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

let regexp = /\d/;

alert( str.match(regexp) ); // 7

Sans l’indicateur g, l’expression régulière ne recherche que la première correspondance, c’est-à-dire le premier chiffre \d.

Ajoutons l’indicateur g pour trouver tous les chiffres :

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

let regexp = /\d/g;

alert( str.match(regexp) ); // liste de correspondances: 7,9,0,3,1,2,3,4,5,6,7

// Obtenons un numéro de télephone composé uniquement de ces chiffres:
alert( str.match(regexp).join('') ); // 79031234567

C’était une classe de caractères pour les chiffres. Il existe également d’autres classes de caractères.

Les plus utilisés sont :

\d (“d” vient de “digit” (“chiffre”))
Un chiffre: un caractère de 0 à 9.
\s (“s” vient de “space” (“espace”))
Un symbole d’espace: inclut les espaces, les tabulations \t, les sauts de ligne \n et quelques autres caractères rares, tels que \v, \f et \r.
\w (“w” vient de “word” (“mot”))
Un caractère “verbeux”: soit une lettre de l’alphabet latin, soit un chiffre ou un trait de soulignement _. Les lettres non latines (comme le cyrillique ou l’hindi) n’appartiennent pas au \w.

Par exemple, \d\s\w signifie un “chiffre” suivi d’un “caractère espace” suivi d’un “caractère verbeux”, tel que 1 a.

Une expression régulière peut contenir à la fois des symboles normaux et des classes de caractères.

Par exemple, CSS\d correspond à une chaîne CSS suivi d’un chiffre :

let str = "Is there CSS4?";
let regexp = /CSS\d/

alert( str.match(regexp) ); // CSS4

On peut également utiliser les classes de caractères :

alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5'

La correspondance (chaque classe de caractères d’expression régulière a le caractère de résultat correspondant) :

Classes inverses

Pour chaque classe de caractères, il existe une “classe inverse”, notée avec la même lettre, mais en majuscule.

L’“inverse” signifie qu’il correspond à tous les autres caractères, par exemple :

\D
Non-chiffre: tout caractère sauf \d, par exemple une lettre.
\S
Non-espace: tout caractère sauf \s, par exemple une lettre.
\W
Caractère non verbal : tout sauf \w, par exemple une lettre non latine ou un espace.

Au début du chapitre, nous avons vu comment créer un numéro de téléphone uniquement à partir d’une chaîne telle que +7(903)-123-45-67: trouver tous les chiffres et les concaténer.

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

alert( str.match(/\d/g).join('') ); // 79031234567

Une autre manière, plus courte, consiste à rechercher un motif non numérique \D et à le supprimer de la chaîne:

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

alert( str.replace(/\D/g, "") ); // 79031234567

Un point est “n’importe quel caractère”

Un point . est une classe de caractères spéciale qui correspond à “n’importe quel caractère sauf une nouvelle ligne”.

Par exemple:

alert( "Z".match(/./) ); // Z

Ou au milieu d’une expression régulière:

let regexp = /CS.4/;

alert( "CSS4".match(regexp) ); // CSS4
alert( "CS-4".match(regexp) ); // CS-4
alert( "CS 4".match(regexp) ); // CS 4 (l'espace est aussi un caractère)

Veuillez noter qu’un point signifie “n’importe quel caractère”, mais pas “l’absence de caractère”. Il doit y avoir un caractère avec lequel le faire correspondre :

alert( "CS4".match(/CS.4/) ); // null, pas de correspondance car il n'y a pas de caractère pour le point

Point tel que n’importe quel caractère avec l’indicateur “s”

Par défaut, un point ne correspond pas au caractère de saut de ligne \n.

Par exemple, l’expression rationnelle A.B correspond à A, puis B avec n’importe quel caractère entre eux, sauf un saut de ligne \n:

alert( "A\nB".match(/A.B/) ); // null (pas de correspondance)

Il existe de nombreuses situations où nous aimerions qu’un point signifie littéralement “n’importe quel caractère”, y compris le saut de ligne.

C’est ce que fait l’indicateur s. Si une expression rationnelle l’a, alors un point . correspond littéralement à n’importe quel caractère :

alert( "A\nB".match(/A.B/s) ); // A\nB (correspondance!)
Non pris en charge par IE

Le flag s n’est pas pris en charge dans IE.

Heureusement, il existe une alternative qui fonctionne partout. Nous pouvons utiliser une expression rationnelle comme [\s\S] pour faire correspondre “n’importe quel caractère” (ce modèle sera traité dans l’article Article "regex-character-sets-and-ranges" non trouvé).

alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (correspondance!)

Le motif [\s\S] dit littéralement: “un caractère espace OU pas un caractère espace”. En d’autres termes, “n’importe quoi”. Nous pourrions utiliser une autre paire de classes complémentaires, telles que [\d\D], cela n’a pas d’importance. Ou même le [^] – car cela signifie correspondre à n’importe quel caractère sauf rien.

Nous pouvons également utiliser cette astuce si nous voulons les deux types de “points” dans le même motif: le point réel . se comportant de manière habituelle (“ne pas inclure de saut de ligne”) est également une facon de correspondre à “n’importe quel caractère” avec [\s\S] ou un motif semblable.

Faites attention aux espaces

Habituellement, nous prêtons peu d’attention aux espaces. Pour nous, les chaînes 1-5 et 1 - 5 sont presque identiques.

Mais si une expression régulière ne prend pas en compte les espaces, elle peut ne pas fonctionner.

Essayons de trouver des chiffres séparés par un tiret :

alert( "1 - 5".match(/\d-\d/) ); // null, pas de correspondance!

Corrigeons-le en ajoutant des espaces dans l’expression régulière \d - \d :

alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, désormais, cela fonctionne
// ou on peut utiliser la classe \s:
alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, fonctionne aussi

Un espace est un caractère. Aussi important que n’importe quel autre caractère.

Nous ne pouvons pas ajouter ou supprimer des espaces dans une expression régulière et nous attendre à ce que cela fonctionne de la même manière.

En d’autres termes, dans une expression régulière, tous les caractères comptent, les espaces aussi.

Résumé

Il existe les classes de caractères suivantes :

  • \d – chiffres.
  • \D – non-chiffres.
  • \s – symboles d’espace, tabulations, sauts de ligne.
  • \S – tout sauf \s.
  • \w – Lettres latines, chiffres, soulignement '_'.
  • \W – tout sauf \w.
  • . – n’importe quel caractère avec l’indicateur d’expression régulière 's', sinon tout sauf un saut de ligne \n.

…Mais ce n’est pas tout!

Le codage Unicode, utilisé par JavaScript pour les chaînes de caractères, fournit de nombreuses propriétés aux caractères, tels que : à quelle langue la lettre appartient (si c’est une lettre), si c’est un signe de ponctuation, etc.

Nous pouvons également faire une recherche selon leurs propriétés. Cela nécessite l’indicateur u, couvert dans le prochain article.

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…)