Expressions régulières JavaScript. Utiliser l'expression régulière en Javascript

La classe RegExp en JavaScript est une expression régulière - un objet qui décrit un modèle de caractère. Les objets RegExp sont généralement créés à l'aide de la syntaxe littérale spéciale indiquée ci-dessous, mais peuvent également être créés à l'aide du constructeur RegExp().

Syntaxe

// en utilisant une syntaxe littérale spéciale var regex = /motif /flags ; // en utilisant le constructeur var regex = new RegExp("motif", "indicateurs"); var regex = new RegExp(/pattern /, "flags");

Valeurs des paramètres :

Indicateurs d'expression régulière

DrapeauLa description
gVous permet de trouver toutes les correspondances au lieu de vous arrêter après la première correspondance ( drapeau de match global).
jePermet la correspondance insensible à la casse ( indicateur d'ignorer la casse).
mLa correspondance se fait sur plusieurs lignes. Le traitement des caractères de début et de fin (^ et $) s'effectue sur plusieurs lignes, c'est-à-dire que la correspondance se produit au début ou à la fin de chaque ligne (séparateurs \n ou \r), et pas seulement au début ou à la fin de la ligne entière ( drapeau multiligne).
tuLe modèle sera traité comme une séquence de points de code Unicode ( drapeau unicode).
yLa correspondance se produit à l'index pointé par la propriété lastIndex de cette expression régulière, tandis que la correspondance n'est pas effectuée à un index ultérieur ou antérieur ( drapeau collant).

Jeux de caractères

Métacaractères

SymboleLa description
. Correspond à un caractère autre que la nouvelle ligne ou la fin de ligne (\n, \r, \u2028 ou \u2029).
\réPermet de rechercher un caractère numérique dans l'alphabet latin de base. Équivalent à l'utilisation du jeu de caractères .
\RÉPermet de trouver n'importe quel caractère qui n'est pas un chiffre de l'alphabet latin de base. Équivalent au jeu de caractères [^0-9].
\sVous permet de trouver un seul caractère d'espacement. Un caractère d'espacement fait référence à un espace, une tabulation, un saut de page, un saut de ligne et d'autres caractères d'espacement Unicode. Équivalent au jeu de caractères [\f\n\r\t\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004​\u2005\u2006​\u2007\u2008​\u2009\ u200a​ \u2028\u2029​​\u202f\u205f​\u3000].
\SVous permet de trouver un seul caractère qui n'est pas un espace. Un caractère d'espacement fait référence à un espace, une tabulation, un saut de page, un saut de ligne et d'autres caractères d'espacement Unicode. Équivalent au jeu de caractères [^ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004​\u2005\u2006​\u2007\u2008​\u2009 \u200a ​\u2028\u2029​​\u202f\u205f​\u3000].
[\b]Permet de trouver le caractère de retour arrière (caractère spécial \b, U+0008).
\0 Permet de trouver le caractère 0 (zéro).
\nPermet de trouver le caractère de saut de ligne.
\FPermet de trouver le caractère de traduction de la page.
\rRecherche un caractère de retour chariot.
\tRecherche un caractère de tabulation horizontale.
\vRecherche un caractère de tabulation verticale.
\wPermet de trouver n'importe quel caractère alphanumérique de l'alphabet latin de base, y compris le trait de soulignement. Équivalent au jeu de caractères .
\WPermet de trouver n'importe quel caractère qui n'est pas un caractère de l'alphabet latin de base. Équivalent au jeu de caractères [^a-Za-z0-9_].
\cXPermet de rechercher un caractère de contrôle dans une chaîne. Où X est une lettre de A à Z. Par exemple, /\cM/ représente le caractère Ctrl-M.
\xhhPermet de rechercher un caractère à l'aide d'une valeur hexadécimale (hh est une valeur hexadécimale à deux chiffres).
\uhhhhVous permet de rechercher un caractère à l'aide de l'encodage UTF-16 (hhhh est une valeur hexadécimale à quatre chiffres).
\u(hhhh) ou
\u(hhhhh)
Recherche un caractère avec une valeur Unicode de U+hhhh ou U+hhhhh (valeur hexadécimale). Uniquement lorsque le drapeau u est défini.
\ Indique que le caractère suivant est spécial et ne doit pas être interprété littéralement. Pour les caractères qui sont normalement traités de manière spéciale, indique que le caractère suivant n'est pas spécial et doit être interprété littéralement.

Restrictions

Quantificateurs

SymboleLa description
n*Correspond à toute chaîne contenant zéro ou plusieurs occurrences d'un caractère n.
n+La correspondance se produit sur toute chaîne contenant au moins un caractère n.
n?Correspond à n'importe quelle chaîne avec un élément précédent n zéro ou une fois.
n(x)Correspond à toute chaîne contenant une séquence de caractères n un certain nombre de fois X. X
n(x,) X occurrences de l'élément précédent n. X doit être un entier positif.
n(x, y)Correspond à toute chaîne contenant au moins X, mais pas plus de y occurrences de l'élément précédent n. X et y doivent être des entiers positifs.
n* ?
n+ ?
n??
n(x) ?
n(x,) ?
n(x,y) ?
L'appariement se fait par analogie avec les quantificateurs *, +, ? et (...), cependant, la recherche porte sur la plus petite correspondance possible. Le mode par défaut est le mode "gourmand", ? à la fin du quantificateur permet de spécifier un mode "non gourmand" dans lequel la répétition de la correspondance se produit le nombre de fois minimum possible.
x(?=y)Faisons correspondre X, seulement si pour X devraient y.
x(?!y)Faisons correspondre X, seulement si pour X ça ne suit pas y.
x|yLa correspondance se produit par rapport à l'une des alternatives spécifiées.

Regroupement et backlinks

SymboleLa description
(X)Trouvons un symbole X et rappelez-vous le résultat du match ("capturer des parenthèses"). La sous-chaîne correspondante peut être appelée à partir des éléments du tableau résultant ..., [n], ou à partir des propriétés de l'objet RegExp prédéfini $1 ..., $9.
(?:X)Trouvons un symbole X, mais ne vous souvenez pas du résultat de la correspondance ("parenthèses non capturantes"). La sous-chaîne correspondante ne peut pas être appelée à partir des éléments du tableau résultant ..., [n], ou à partir des propriétés de l'objet RegExp prédéfini $1 ..., $9.
\nRéférence arrière à la dernière sous-chaîne qui correspond à la nième sous-chaîne entre parenthèses dans l'expression régulière (les crochets sont numérotés de gauche à droite). n doit être un entier positif.

Certaines personnes, lorsqu'elles sont confrontées à un problème, pensent : "Oh, j'utilise des expressions régulières". Maintenant, ils ont deux problèmes.
Jamie Zawinski

Yuan-Ma a déclaré : « Il faut une grande force pour couper du bois à travers la structure en bois. Il faut beaucoup de code pour programmer à travers la structure du problème.
Maître Yuan-Ma, "Livre de programmation"

Les outils et techniques de programmation survivent et prolifèrent de manière chaotique et évolutive. Parfois, ce ne sont pas les beaux et les brillants qui survivent, mais ceux qui réussissent raisonnablement bien dans leur domaine, par exemple s'ils sont intégrés à une autre technologie performante.

Dans ce chapitre, nous aborderons un tel outil, les expressions régulières. C'est une façon de décrire des modèles dans des données de chaîne. Ils créent un petit langage séparé qui est inclus dans JavaScript et de nombreux autres langages et outils.

Les habitués sont à la fois très étranges et extrêmement utiles. Leur syntaxe est cryptique et l'API JavaScript est maladroite pour eux. Mais c'est un outil puissant pour l'exploration et la manipulation de chaînes. En les comprenant, vous deviendrez un programmeur plus efficace.

Créer une expression régulière

Régulier - type d'objet. Il peut être créé en appelant le constructeur RegExp ou en écrivant le modèle souhaité, entouré de barres obliques.

Var re1 = new RegExp("abc"); var re2 = /abc/;

Ces deux expressions régulières représentent le même modèle : le caractère "a" suivi du caractère "b" suivi du caractère "c".

Si vous utilisez le constructeur RegExp, le modèle est écrit comme chaîne simple, donc toutes les règles concernant les barres obliques inverses s'appliquent.

La deuxième entrée, où le modèle est entre barres obliques, gère les barres obliques inverses différemment. Tout d'abord, puisque le modèle se termine par une barre oblique, nous devons mettre une barre oblique inverse avant la barre oblique que nous voulons inclure dans notre modèle. De plus, les barres obliques inverses qui ne font pas partie de caractères spéciaux le type \n sera conservé (plutôt qu'ignoré comme dans les chaînes) et changera la signification du modèle. Certains caractères, tels que le point d'interrogation ou le signe plus, ont une signification particulière dans les expressions régulières, et si vous avez besoin de trouver un tel caractère, il doit également être précédé d'une barre oblique inverse.

Var8eenPlus = /dix-huit\+/;

Pour savoir quels caractères faire précéder d'une barre oblique, vous devez connaître la liste de tous les caractères spéciaux dans les expressions régulières. Ce n'est pas encore réaliste, donc en cas de doute, mettez simplement une barre oblique inverse avant tout caractère qui n'est pas une lettre, un chiffre ou un espace.

Vérification des correspondances

Les expressions régulières ont plusieurs méthodes. Le plus simple est le test. Si vous lui transmettez une chaîne, il renverra un booléen indiquant si la chaîne contient une occurrence du motif donné.

Console.log(/abc/.test("abcde")); // → vrai console.log(/abc/.test("abxde")); // → faux

Un régulier composé uniquement de caractères non spéciaux est simplement une séquence de ces caractères. Si abc est n'importe où dans la chaîne que nous testons (pas seulement au début), test renverra true.

Recherche d'un jeu de caractères

Savoir si une chaîne contient abc pourrait également être fait en utilisant indexOf. Les regulars permettent d'aller plus loin et de composer des motifs plus complexes.

Disons que nous devons trouver n'importe quel nombre. Lorsque nous mettons un ensemble de caractères entre crochets dans une expression régulière, cela signifie que cette partie de l'expression correspond à l'un des caractères entre crochets.

Les deux expressions sont sur des lignes contenant un chiffre.

Console.log(//.test("en 1992")); // → vrai console.log(//.test("en 1992")); // → vrai

Entre crochets, un tiret entre deux caractères est utilisé pour spécifier une plage de caractères, où la séquence est spécifiée par le codage Unicode. Les caractères de 0 à 9 sont là juste dans une rangée (codes de 48 à 57), donc il les capture tous et correspond à n'importe quel chiffre.

Plusieurs groupes de caractères ont leurs propres abréviations intégrées.

\d N'importe quel chiffre
\w Caractère alphanumérique
\s Caractère d'espacement (espace, tabulation, saut de ligne, etc.)
\D n'est pas un chiffre
\W n'est pas un caractère alphanumérique
\S caractère non blanc
. n'importe quel caractère sauf nouvelle ligne

Ainsi, vous pouvez définir le format de la date et de l'heure comme 30-01-2003 15:20 avec l'expression suivante :

Var dateHeure = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/ ; console.log(dateTime.test("30-01-2003 15:20")); // → vrai console.log(dateTime.test("30-jan-2003 15:20")); // → faux

Ça a l'air terrible, n'est-ce pas ? Il y a trop de barres obliques inverses qui rendent difficile la compréhension du modèle. Plus tard, nous l'améliorerons légèrement.

Les barres obliques inverses peuvent également être utilisées entre crochets. Par exemple, [\d.] signifie n'importe quel nombre ou point. Notez que le point à l'intérieur des crochets perd sa signification particulière et devient juste un point. Il en va de même pour les autres caractères spéciaux comme +.

Vous pouvez inverser un jeu de caractères - c'est-à-dire que vous devez trouver n'importe quel caractère autre que ceux du jeu - en plaçant un signe ^ immédiatement après le crochet ouvrant.

Var notBinary = /[^01]/; console.log(notBinary.test("1100100010100110")); // → faux console.log(notBinary.test("1100100010200110")); // → vrai

Répétition des parties du motif

Nous savons trouver un chiffre. Mais que se passe-t-il si nous devons trouver le nombre entier - une séquence d'un ou plusieurs chiffres ?

Si vous mettez un signe + après quelque chose dans l'expression régulière, cela signifie que cet élément peut être répété plus d'une fois. /\d+/ signifie un ou plusieurs chiffres.

Console.log(/"\d+"/.test(""123"")); // → vrai console.log(/"\d+"/.test("""")); // → faux console.log(/"\d*"/.test(""123"")); // → vrai console.log(/"\d*"/.test("""")); // → vrai

L'astérisque * a presque la même signification, mais il permet au motif d'apparaître zéro fois. S'il y a un astérisque après quelque chose, cela n'empêche jamais le motif d'être dans la chaîne - il y apparaît juste zéro fois.

Le point d'interrogation rend la partie de motif facultative, ce qui signifie qu'elle peut se produire zéro ou une fois. Dans l'exemple suivant, le caractère u peut apparaître, mais le modèle correspond quand ce n'est pas le cas.

Var voisin = /voisin?r/; console.log(neighbor.test("neighbor")); // → vrai console.log(neighbor.test("neighbor")); // → vrai

Pour spécifier le nombre exact de fois qu'un modèle doit se produire, utilisez un appareil dentaire. (4) après l'élément signifie qu'il doit apparaître 4 fois dans la ligne. Vous pouvez également spécifier un espace : (2,4) signifie que l'élément doit apparaître au moins 2 et au plus 4 fois.

Une autre version du format de date et d'heure, où les jours, les mois et les heures à un ou deux chiffres sont autorisés. Et c'est aussi un peu plus lisible.

Var dateHeure = /\d(1,2)-\d(1,2)-\d(4) \d(1,2):\d(2)/; console.log(dateTime.test("30-1-2003 8:45")); // → vrai

Vous pouvez utiliser des espaces ouverts en omettant l'un des nombres. (,5) signifie que le motif peut se produire de zéro à cinq fois, et (5,) - de cinq fois ou plus.

Groupement de sous-expressions

Les parenthèses peuvent être utilisées pour utiliser les opérateurs * ou + sur plusieurs éléments à la fois. La partie de l'expression régulière entre parenthèses est considérée comme un élément du point de vue des opérateurs.

Var cartoonCrying = /boo+(hoo+)+/i; console.log(cartoonCrying.test("Boohoooohoohooo")); // → vrai

Les premier et deuxième plus ne s'appliquent qu'au deuxième o dans boo et hoo. Le troisième + fait référence à l'ensemble du groupe (hoo+), trouvant une ou plusieurs de ces séquences.

La lettre i à la fin de l'expression rend l'expression régulière insensible à la casse, de sorte que B est identique à b.

Matches et groupes

La méthode de test est la méthode la plus simple pour vérifier les expressions régulières. Il signale uniquement si une correspondance a été trouvée ou non. Les expressions régulières ont également une méthode exec qui renverra null si rien n'a été trouvé, et sinon renverra un objet avec des informations sur la correspondance.

Varmatch = /\d+/.exec("un deux 100"); journal de la console (correspondance); // → ["100"] console.log(match.index); // → 8

L'objet exec retourné a propriété d'indexation, qui contient le numéro du caractère correspondant. En général, l'objet ressemble à un tableau de chaînes, où le premier élément est la chaîne dont la correspondance a été vérifiée. Dans notre exemple, ce sera la séquence de nombres que nous recherchions.

Les chaînes ont une méthode de correspondance qui fonctionne à peu près de la même manière.

Console.log("un deux 100".match(/\d+/)); // → ["100"]

Lorsqu'une expression régulière contient des sous-expressions regroupées entre parenthèses, le texte correspondant à ces groupes apparaît également dans le tableau. Le premier élément est toujours le match entier. Le second est la partie qui correspondait au premier groupe (celui avec parenthèses rencontré en premier), puis au second groupe, et ainsi de suite.

Var quotedText = /"([^"]*)"/ ; console.log(quotedText.exec("elle a dit "bonjour"")); // → [""bonjour"", "bonjour"]

Lorsqu'un groupe n'est pas trouvé du tout (par exemple, s'il est suivi d'un point d'interrogation), sa position dans le tableau contient undefined. Si le groupe a correspondu plusieurs fois, seule la dernière correspondance sera dans le tableau.

Console.log(/bad(ly)?/.exec("bad")); // → ["mauvais", indéfini] console.log(/(\d)+/.exec("123")); // → ["123", "3"]

Les groupes sont utiles pour extraire des parties de chaînes. Si nous ne voulons pas seulement vérifier si une chaîne contient une date, mais l'extraire et créer un objet représentant la date, nous pouvons mettre des séquences de nombres entre parenthèses et sélectionner la date à partir du résultat de exec.

Mais pour commencer petite parenthèse, dans lequel nous apprenons la manière préférée de stocker les dates et les heures en JavaScript.

type de date

JavaScript a un type d'objet standard pour les dates - plus précisément, les moments dans le temps. Ça s'appelle Rendez-vous. Si vous créez simplement un objet de date avec new, vous obtiendrez date actuelle et une ceinture.

Console.log(nouvelle Date()); // → Dim 09 novembre 2014 00:07:57 GMT+0300 (CET)

Vous pouvez également créer un objet contenant l'heure donnée

Console.log(nouvelle date(2015, 9, 21)); // → Mer 21 octobre 2015 00:00:00 GMT+0300 (CET) console.log(new Date(2009, 11, 9, 12, 59, 59, 999)); // → Mer 09 Déc 2009 12:59:59 GMT+0300 (CET)

JavaScript utilise une convention où les numéros de mois commencent à zéro et les numéros de jour commencent à un. C'est stupide et ridicule. Chercher.

Les quatre derniers arguments (heures, minutes, secondes et millisecondes) sont facultatifs et mis à zéro s'ils ne sont pas présents.

Les horodatages sont stockés en nombre de millisecondes depuis le début de 1970. Pour les périodes antérieures à 1970, des nombres négatifs sont utilisés (cela est dû à la convention temporelle Unix qui a été créée à cette époque). La méthode getTime de l'objet date renvoie ce nombre. C'est grand, bien sûr.
console.log(nouvelle Date(2013, 11, 19).getTime()); // → 1387407600000 console.log(nouvelle Date(1387407600000)); // → jeu 19 déc. 2013 00:00:00 GMT+0100 (CET)

Si vous donnez au constructeur Date un seul argument, il est traité comme ce nombre de millisecondes. Vous pouvez obtenir la valeur actuelle en millisecondes en créant un objet Date et en appelant la méthode getTime ou en appelant la fonction Date.now.

L'objet Date possède les méthodes getFullYear, getMonth, getDate, getHours, getMinutes et getSeconds pour récupérer ses composants. Il existe également une méthode getYear qui renvoie un code à deux chiffres plutôt inutile comme 93 ou 14.

En mettant les parties souhaitées du modèle entre parenthèses, nous pouvons créer un objet date directement à partir de la chaîne.

Fonction findDate(string) ( var dateTime = /(\d(1,2))-(\d(1,2))-(\d(4))/; var match = dateTime.exec(string); return new Date(Number(match), Number(match) - 1, Number(match)); ) console.log(findDate("30-1-2003")); // → Jeu 30 janvier 2003 00:00:00 GMT+0100 (CET)

Limites de mots et de lignes

Malheureusement, findDate extraira tout aussi volontiers la date sans signification 00-1-3000 de la chaîne "100-1-30000". La correspondance peut se produire n'importe où dans la chaîne, donc dans ce cas, elle commencera simplement au deuxième caractère et se terminera à l'avant-dernier.

Si nous devons forcer la correspondance à prendre la chaîne entière, nous utilisons les marques ^ et $. ^ correspond au début de la chaîne et $ correspond à la fin. Par conséquent, /^\d+$/ correspond à une chaîne composée uniquement d'un ou plusieurs chiffres, /^!/ correspond à une ligne commençant par point d'exclamation, et /x^/ ne correspond à aucune ligne (il ne peut pas y avoir de x avant le début d'une ligne).

Si, d'autre part, nous voulons simplement nous assurer que la date commence et se termine sur une limite de mot, nous utilisons la marque \b. Une limite de mot peut être le début ou la fin d'une ligne, ou n'importe quel endroit d'une ligne où le caractère \w est alphanumérique d'un côté et non alphanumérique de l'autre.

Console.log(/cat/.test("concatener")); // → vrai console.log(/\bcat\b/.test("concatener")); // → faux

Notez que l'étiquette de limite n'est pas un caractère. C'est juste une contrainte, ce qui signifie qu'une correspondance ne se produit que si une certaine condition est remplie.

Modèles de choix

Disons que nous devons savoir si le texte contient non seulement un nombre, mais un nombre suivi de cochon, vache ou poulet au singulier ou au pluriel.

Il serait possible d'écrire trois expressions régulières et de les vérifier une par une, mais il existe un meilleur moyen. Symbole | indique un choix entre les motifs à gauche et à droite de celui-ci. Et vous pouvez dire ce qui suit :

Var animalCount = /\b\d+ (porc|vache|poulet)s?\b/ ; console.log(animalCount.test("15 cochons")); // → vrai console.log(animalCount.test("15 cochons poulets")); // → faux

Les parenthèses délimitent la partie du motif à laquelle | est appliqué, et vous pouvez mettre plusieurs de ces opérateurs l'un après l'autre pour indiquer un choix de plus de deux options.

Moteur de recherche

Les expressions régulières peuvent être considérées comme des organigrammes. Le schéma suivant décrit le dernier exemple d'élevage.

Une expression correspond à une chaîne si un chemin peut être trouvé du côté gauche du diagramme vers la droite. Nous nous souvenons de la position actuelle dans la chaîne, et chaque fois que nous passons devant le rectangle, nous vérifions que la partie de la chaîne juste après notre position correspond au contenu du rectangle.

Ainsi, la vérification de la correspondance de notre expression régulière dans la chaîne "les 3 cochons" lors du passage dans l'organigramme ressemble à ceci :

Il y a une limite de mot à la position 4, et nous passons par le premier rectangle
- à partir de la 4ème position, on trouve le nombre, et on passe par le deuxième rectangle
- à la position 5, un chemin se referme avant le deuxième rectangle, et le second va plus loin jusqu'au rectangle avec un espace. Nous avons un espace, pas un nombre, et nous choisissons le deuxième chemin.
- nous sommes maintenant à la position 6, au début des "cochons", et à la triple bifurcation des chemins. Il n'y a pas de "vache" ou de "poulet" dans la chaîne, mais il y a "cochon", donc nous choisissons ce chemin.
- en position 9 après la triple fourche, un chemin contourne le "s" et va jusqu'au dernier rectangle avec une frontière de mot, et le second passe par le "s". Nous avons "s", donc nous y allons.
- à la position 10, nous sommes à la fin de la ligne, et seule une limite de mot peut correspondre. La fin de la ligne est considérée comme une frontière et nous traversons le dernier rectangle. Et nous avons donc réussi à trouver notre modèle.

Fondamentalement, les expressions régulières fonctionnent comme ceci : l'algorithme commence au début de la chaîne et essaie d'y trouver une correspondance. Dans notre cas, il y a une limite de mot là-bas, donc elle dépasse le premier rectangle - mais il n'y a pas de numéro, donc elle trébuche sur le deuxième rectangle. Ensuite, il passe au deuxième caractère de la chaîne et essaie d'y trouver une correspondance... Et ainsi de suite, jusqu'à ce qu'il trouve une correspondance ou atteigne la fin de la chaîne, auquel cas aucune correspondance n'est trouvée.

Pots-de-vin

Le /\b(+b|\d+|[\da-f]h)\b/ régulier correspond soit à un nombre binaire suivi d'un b, soit à un nombre décimal sans suffixe, soit à un nombre hexadécimal (chiffres de 0 à 9 ou caractères de a à h), suivi de h. Diagramme pertinent :

Lors de la recherche d'une correspondance, il peut arriver que l'algorithme prenne le chemin supérieur (nombre binaire), même s'il n'y a pas un tel nombre dans la chaîne. S'il y a une chaîne "103", par exemple, il est clair que ce n'est qu'après avoir atteint le nombre 3 que l'algorithme comprendra qu'il est sur le mauvais chemin. En général, la chaîne correspond à l'expression régulière, mais pas dans cette branche.

Ensuite, l'algorithme revient en arrière. A la bifurcation, il se souvient de la position courante (dans notre cas, c'est le début de la ligne, juste après le mot limite) afin que vous puissiez revenir en arrière et essayer un autre chemin si celui choisi ne fonctionne pas. Pour la chaîne "103", après avoir rencontré un triplet, il reviendra et essaiera de suivre le chemin des nombres décimaux. Cela fonctionnera, donc une correspondance sera trouvée.

L'algorithme s'arrête dès qu'il trouve une correspondance parfaite. Cela signifie que même si plusieurs options peuvent convenir, une seule d'entre elles est utilisée (dans l'ordre dans lequel elles apparaissent en saison régulière).

Le retour en arrière se produit lors de l'utilisation d'opérateurs de répétition tels que + et *. Si vous recherchez /^.*x/ dans la chaîne "abcxe", la partie.* de la regex essaiera de consommer la chaîne entière. L'algorithme réalisera alors qu'il a également besoin de "x". Puisqu'il n'y a pas de "x" après la fin de la chaîne, l'algorithme essaiera de trouver une correspondance en revenant en arrière d'un caractère. Il n'y a pas non plus de x après abcx, puis il revient en arrière, déjà à la sous-chaîne abc. Et après la ligne, il trouve x et signale une correspondance réussie, aux positions 0 à 4.

Vous pouvez écrire une expression régulière qui conduira à plusieurs rollbacks. Ce problème se produit lorsque le modèle peut correspondre aux données d'entrée dans un ensemble différentes façons. Par exemple, si nous commettons une erreur lors de l'écriture d'une expression régulière pour les nombres binaires, nous pourrions accidentellement écrire quelque chose comme /(+)+b/.

Si l'algorithme recherche un tel modèle dans une longue chaîne de 0 et de 1 qui ne se termine pas par un "b", il passera d'abord par la boucle interne jusqu'à ce qu'il n'y ait plus de chiffres. Ensuite, il remarquera qu'il n'y a pas de «b» à la fin, reculera d'une position, parcourra la boucle externe, abandonnera à nouveau, essaiera de reculer d'une position de plus le long de la boucle interne ... Et il continuera à chercher de cette façon, en utilisant les deux boucles. Autrement dit, la quantité de travail avec chaque caractère de la chaîne doublera. Même pour quelques dizaines de personnages, la recherche d'une correspondance prendra beaucoup de temps.

remplacer la méthode

Les chaînes ont une méthode de remplacement qui peut remplacer une partie d'une chaîne par une autre chaîne.

Console.log("papa".replace("n", "m")); // → carte

Le premier argument peut également être un argument régulier, auquel cas la première occurrence de l'expression régulière dans la chaîne est remplacée. Lorsque l'option "g" (globale) est ajoutée à l'expression régulière, toutes les occurrences sont remplacées, pas seulement la première.

Console.log("Borobudur".replace(//, "a")); // → Barobudur console.log("Borobudur".replace(//g, "a")); // → Barabadar

Il serait logique de passer l'option "remplacer tout" via un argument séparé, ou via une méthode séparée comme replaceAll. Mais malheureusement, l'option est passée par l'expression régulière elle-même.

La pleine puissance des expressions régulières est révélée lorsque nous utilisons des références aux groupes trouvés dans la chaîne spécifiée dans l'expression régulière. Par exemple, nous avons une chaîne contenant des noms de personnes, un nom par ligne, au format LastName, FirstName. Si nous devons les échanger et supprimer la virgule pour obtenir "Prénom Nom", nous écrivons ce qui suit :

Console.log("Hopper, Grace\nMcCarthy, John\nRitchie, Dennis" .replace(/([\w ]+), ([\w ]+)/g, "$2 $1")); // → Grace Hopper // John McCarthy // Dennis Ritchie

$1 et $2 dans la chaîne de remplacement font référence à des groupes de caractères entre parenthèses. $1 est remplacé par le texte correspondant au premier groupe, $2 par le deuxième groupe, et ainsi de suite, jusqu'à $9. La correspondance entière est contenue dans la variable $&.

Vous pouvez également passer une fonction comme deuxième argument. Pour chaque remplacement, une fonction sera appelée, dont les arguments seront les groupes trouvés (et toute la partie correspondante de la chaîne dans son ensemble), et son résultat sera inséré dans une nouvelle chaîne.

Exemple simple :

Vars = "la cia et le fbi" ; console.log(s.replace(/\b(fbi|cia)\b/g, function(str) ( return str.toUpperCase(); ))); // → la CIA et le FBI

Et en voici une plus intéressante :

Bouillon Var = "1 citron, 2 choux et 101 oeufs" ; function minusOne(match, amount, unit) (mount = Number(amount) - 1; if (amount == 1) // il n'en reste qu'un, supprimer "s" à la fin unit = unit.slice(0, unit.length - 1); sinon si (montant == 0) montant = "non"; retour montant + " " + unité; ) console.log(stock.replace(/(\d+) (\w+)/g, minusOne)) ; // → pas de citron, 1 chou et 100 œufs

Le code prend une chaîne, trouve toutes les occurrences de nombres suivis d'un mot et renvoie une chaîne où chaque nombre est réduit de un.

Le groupe (\d+) va dans l'argument quantité, et le groupe (\w+) va dans l'unité. La fonction convertit le montant en un nombre - et cela fonctionne toujours, car notre modèle est simplement \d+. Et puis il apporte des modifications au mot, au cas où il ne resterait qu'un seul élément.

Cupidité

Il est facile d'écrire une fonction en utilisant replace pour supprimer tous les commentaires du code JavaScript. Voici la première tentative :

Fonction stripComments(code) ( code de retour.replace(/\/\/.*|\/\*[^]*\*\//g, ""); ) console.log(stripComments("1 + /* 2*/3"); // → 1 + 3 console.log(stripComments("x = 10;// dix!")); // → x = 10 ; console.log(stripComments("1 /* a */+/* b */ 1"); // → 1 1

La partie avant l'opérateur "ou" correspond à deux barres obliques suivies d'un nombre quelconque de caractères, à l'exception des caractères de saut de ligne. La partie qui supprime les commentaires multi-lignes est plus compliquée. Nous utilisons [^], c'est-à-dire n'importe quel caractère non vide comme moyen de trouver n'importe quel caractère. Nous ne pouvons pas utiliser de point car les commentaires bloqués continuent sur nouvelle ligne, et le caractère de saut de ligne ne correspond pas au point.

Mais la sortie de l'exemple précédent est erronée. Pourquoi?

La partie [^]* essaiera d'abord de saisir autant de caractères que possible. Si, à cause de cela, la partie suivante de l'expression régulière ne trouve pas de correspondance pour elle-même, elle reviendra en arrière d'un caractère et réessayera. Dans l'exemple, l'algorithme essaie de capturer la chaîne entière, puis revient en arrière. En reculant de 4 caractères, il trouvera */ dans la ligne - et ce n'est pas ce que nous voulions. Nous voulions saisir un seul commentaire, ne pas aller au bout de la ligne et trouver le dernier commentaire.

Pour cette raison, nous disons que les opérateurs de répétition (+, *, ? et ()) sont gourmands, c'est-à-dire qu'ils saisissent d'abord autant qu'ils le peuvent, puis reviennent en arrière. Si vous posez une question après un tel opérateur (+?, *?, ??, ()?), ils deviennent non gourmands et commencent à trouver les plus petites occurrences possibles.

Et c'est ce dont nous avons besoin. En faisant correspondre l'astérisque au nombre minimum de caractères possibles sur la ligne, nous ne consommons qu'un seul bloc de commentaires, et pas plus.

Fonction stripComments(code) ( code de retour.replace(/\/\/.*|\/\*[^]*?\*\//g, ""); ) console.log(stripComments("1 /* a */+/* b */ 1")); // → 1 + 1

De nombreuses erreurs se produisent lors de l'utilisation d'opérateurs gourmands au lieu d'opérateurs non gourmands. Lorsque vous utilisez l'opérateur de répétition, considérez toujours l'opérateur non gourmand en premier.

Création dynamique d'objets RegExp

Dans certains cas, le modèle exact n'est pas connu au moment où le code est écrit. Par exemple, vous devrez rechercher un nom d'utilisateur dans le texte et le placer entre des traits de soulignement. Comme vous ne reconnaîtrez le nom qu'après l'exécution du programme, vous ne pouvez pas utiliser la notation slash.

Mais vous pouvez créer une chaîne et utiliser le constructeur RegExp. Voici un exemple:

var nom = "harry" ; var text = "Harry a une cicatrice sur le front."; var regexp = new RegExp("\\b(" + nom + ")\\b", "gi"); console.log(text.replace(regexp, "_$1_")); // → Et _Harry_ a une cicatrice sur le front.

Lors de la création de limites de mots, nous devons utiliser des doubles barres obliques, car nous les écrivons sur une ligne normale et non dans une expression régulière avec des barres obliques. Le deuxième argument de RegExp contient des options pour les expressions régulières - dans notre cas, "gi", c'est-à-dire global et insensible à la casse.

Mais que se passe-t-il si le nom est "dea+hlrd" (si notre utilisateur est un culhacker) ? En conséquence, nous obtenons une expression régulière sans signification qui ne trouvera pas de correspondance dans la chaîne.

Nous pouvons ajouter des barres obliques inverses avant tout caractère que nous n'aimons pas. Nous ne pouvons pas ajouter de barres obliques inverses avant les lettres car \b ou \n sont des caractères spéciaux. Mais ajouter des barres obliques avant tout caractère non alphanumérique est acceptable.

varname = "dea+hlrd" ; var text = "Ce dea+hlrd a eu tout le monde."; var échappé = nom.replace(/[^\w\s]/g, "\\$&"); var regexp = new RegExp("\\b(" + échappé + ")\\b", "gi"); console.log(text.replace(regexp, "_$1_")); // → Ce _dea+hlrd_ a eu tout le monde.

méthode de recherche

La méthode indexOf ne peut pas être utilisée avec des expressions régulières. Mais il existe une méthode de recherche, qui attend juste une expression régulière. Comme indexOf, il renvoie l'index de la première occurrence, ou -1 si ce n'est pas le cas.

Console.log("word".search(/\S/)); // → 2 console.log(" ".recherche(/\S/)); // → -1

Malheureusement, il n'y a aucun moyen de dire à une méthode de rechercher une correspondance commençant à un décalage spécifique (comme vous pouvez le faire avec indexOf). Ce serait utile.

propriété lastIndex

La méthode exec ne fournit pas non plus un moyen pratique de lancer la recherche à partir d'une position donnée dans une chaîne. Mais cela donne un moyen peu pratique.

L'objet regex a des propriétés. L'un d'eux est source, qui contient une chaîne. Un autre est lastIndex , qui contrôle, dans certaines conditions, où la prochaine recherche d'occurrence commencera.

Ces conditions incluent que l'option globale g doit être présente et que la recherche doit être effectuée à l'aide de la méthode exec. Une solution plus intelligente consisterait simplement à autoriser la transmission d'un argument supplémentaire à exec, mais la cohérence n'est pas une fonctionnalité fondamentale de l'interface JavaScript regex.

Modèle de var = /y/g ; motif.dernierIndex = 3 ; varmatch = pattern.exec("xyzzy"); console.log(match.index); // → 4 console.log(pattern.lastIndex); // → 5

Si la recherche a réussi, l'appel exec met à jour la propriété lastIndex pour pointer vers la position après l'occurrence trouvée. S'il n'y a pas eu de succès, lastIndex est mis à zéro - tout comme le lastIndex de l'objet nouvellement créé.

Lors de l'utilisation d'une variable regex globale et de plusieurs appels exec, ces Mises à jour automatiques lastIndex peut entraîner des problèmes. Votre expression régulière peut commencer la recherche à partir de la position à gauche de l'appel précédent.

vardigit = /\d/g; console.log(digit.exec("le voici : 1"); // → ["1"] console.log(digit.exec("et maintenant : 1")); // → nul

Un autre effet intéressant de l'option g est qu'elle modifie le fonctionnement de la méthode de correspondance. Lorsqu'il est appelé avec cette option, au lieu de renvoyer un tableau similaire au résultat d'un exec, il trouve toutes les occurrences du motif dans une chaîne et renvoie un tableau des sous-chaînes qu'il trouve.

Console.log("Banane".match(/en/g)); // → ["fr", "fr"]

Soyez donc prudent avec les variables régulières globales. Les cas où ils sont nécessaires - appels à remplacer ou endroits où vous utilisez spécifiquement lastIndex - sont probablement tous les cas dans lesquels ils doivent être utilisés.

Boucles sur les occurrences

Une tâche typique consiste à itérer sur toutes les occurrences d'un modèle dans une chaîne afin que vous puissiez accéder à l'objet match dans le corps de la boucle à l'aide de lastIndex et exec.

Var input = "Une chaîne contenant 3 nombres... 42 et 88."; numéro_var = /\b(\d+)\b/g ; varmatch ; while (match = number.exec(input)) console.log("Found ", match, " on ", match.index); // → Trouvé 3 par 14 // Trouvé 42 par 33 // Trouvé 88 par 40

Le fait que la valeur de l'affectation est la valeur affectée est utilisé. En utilisant la construction match = re.exec(input) comme condition dans la boucle while, nous recherchons au début de chaque itération, stockons le résultat dans une variable et terminons la boucle lorsque toutes les correspondances sont trouvées.

Analyse des fichiers INI

A la fin du chapitre, nous considérerons un problème utilisant des expressions régulières. Imaginez que nous écrivions un programme qui collecte automatiquement des informations sur nos ennemis via Internet. (Nous n'écrirons pas tout le programme, seulement la partie qui lit le fichier de paramètres. Désolé.) Le fichier ressemble à ceci :

Moteur de recherche=http://www.google.com/search?q=$1 méchanceté=9.7 ; les commentaires sont précédés d'un point-virgule ; chaque section fait référence à un ennemi différent fullname=Larry Doe type=kindergarten oxen website=http://www.geocities.com/CapeCanaveral/11451 fullname=Gargamel type=evil wizard outputdir=/home/marijn/enemies/gargamel

Le format exact du fichier (qui est assez largement utilisé et communément appelé INI) est le suivant :

Les lignes vides et les lignes commençant par un point-virgule sont ignorées
- les lignes entre crochets commencent une nouvelle section
- lignes contenant un identifiant alphanumérique suivi de = ajouter un paramètre dans cette section

Tout le reste est une donnée incorrecte.

Notre tâche consiste à convertir une telle chaîne en un tableau d'objets, chacun avec une propriété de nom et un tableau de paramètres. Chaque section a besoin d'un objet et d'un autre pour les paramètres globaux en haut du fichier.

Étant donné que le fichier doit être analysé ligne par ligne, c'est une bonne idée de commencer par diviser le fichier en lignes. Pour ce faire, nous avons utilisé string.split("\n") au chapitre 6. Certains systèmes d'exploitation n'utilisent pas un caractère \n, mais deux \r\n pour le saut de ligne. Étant donné que la méthode split prend des expressions régulières comme argument, nous pouvons diviser les lignes à l'aide de l'expression /\r?\n/ , qui autorise à la fois \n et \r\n simples entre les lignes.

Function parseINI(string) ( // Commençons par un objet contenant les paramètres haut niveau var currentSection = (nom : null, champs : ); var catégories = ; string.split(/\r?\n/).forEach(function(line) ( var match; if (/^\s*(;.*)?$/.test(line)) ( return; ) else if (match = line.match(/^\[(.*)\]$/)) ( currentSection = (name: match, fields: ); categories.push(currentSection); ) else if (match = line.match( /^(\w+)=(.*)$/)) ( currentSection. fields. push((name: match, value: match)); ) else ( throw new Error("Line "" + line + "" contains données erronées."); ) )); catégories de retour ; )

Le code parcourt toutes les lignes, mettant à jour l'objet de la section courante "section courante". Premièrement, il vérifie si la ligne peut être ignorée, en utilisant l'expression régulière /^\s*(;.*)?$/. Pouvez-vous imaginer comment cela fonctionne? La partie entre parenthèses est la même que les commentaires, hein ? fait en sorte que l'expression régulière corresponde également aux lignes composées uniquement d'espaces.

Si la ligne n'est pas un commentaire, le code vérifie s'il commence une nouvelle section. Si oui, cela crée nouvel objet pour la section en cours, à laquelle les paramètres suivants sont ajoutés.

La dernière possibilité significative est que la chaîne soit réglage normal, auquel cas il est ajouté à l'objet courant.

Si aucune des options n'a fonctionné, la fonction renvoie une erreur.

Remarquez comment l'utilisation fréquente de ^ et $ garantit que l'expression correspond à la chaîne entière, et non à une partie de celle-ci. S'ils ne sont pas utilisés, le code fonctionnera généralement, mais parfois il donnera des résultats étranges, et une telle erreur sera difficile à détecter.

La construction if (match = string.match(...)) est comme une astuce utilisant une affectation comme condition dans une boucle while. Souvent, vous ne savez pas que l'appel match réussira, vous ne pouvez donc accéder qu'à l'objet résultant à l'intérieur du bloc if qui le teste. Afin de ne pas casser la belle chaîne des if checks, on affecte le résultat de la recherche à une variable, et on utilise immédiatement cette affectation comme check.

Symboles internationaux

En raison de l'implémentation initialement simple du langage et de la fixation ultérieure d'une telle implémentation « dans le granit », les expressions régulières JavaScript sont muettes avec des caractères qui ne se trouvent pas en anglais. Par exemple, le caractère "lettre" du point de vue des expressions régulières JavaScript peut être l'une des 26 lettres de l'alphabet anglais et, pour une raison quelconque, également un trait de soulignement. Les lettres comme é ou β qui sont uniquement des lettres ne correspondent pas à \w (et correspondront à \W, qui n'est pas une lettre).

Par une étrange coïncidence, historiquement \s (espace) correspond à tous les caractères considérés comme des espaces blancs dans Unicode, y compris des choses comme Espace non-cassant ou le séparateur de voyelles mongoles.

Certaines implémentations d'expressions régulières dans d'autres langages ont une syntaxe spéciale pour rechercher des catégories spéciales de caractères Unicode, telles que "tout en majuscule", "tout en ponctuation" ou "caractères de contrôle". Il est prévu d'ajouter de telles catégories à JavaScript, mais elles ne seront probablement pas implémentées de sitôt.

Résultat

Les réguliers sont des objets représentant des modèles de recherche dans des chaînes. Ils utilisent leur propre syntaxe pour exprimer ces modèles.

/abc/ Séquence de caractères
// N'importe quel caractère de la liste
/[^abc]/ N'importe quel caractère, sauf les caractères de la liste
// N'importe quel caractère entre les deux
/x+/ Une ou plusieurs occurrences du motif x
/x+?/ Une ou plusieurs occurrences, non gourmand
/x*/ Zéro ou plusieurs occurrences
/x?/ Zéro ou une occurrence
/x(2,4)/ Deux à quatre occurrences
/(abc)/ Groupe
/a|b|c/ N'importe quel motif parmi plusieurs
/\d/ N'importe quel chiffre
/\w/ N'importe quel caractère alphanumérique ("lettre")
/\s/ N'importe quel caractère d'espacement
/./ N'importe quel caractère sauf retour à la ligne
/\b/ Limite de mot
/^/ Début de ligne
/$/ Fin de ligne

L'expression régulière a une méthode de test pour vérifier si un motif existe dans une chaîne. Il existe une méthode exec qui renvoie un tableau contenant tous les groupes trouvés. Le tableau a une propriété index, qui contient le numéro du caractère à partir duquel la correspondance s'est produite.

Les chaînes ont une méthode de correspondance pour rechercher des modèles et une méthode de recherche qui renvoie uniquement la position de départ de l'occurrence. La méthode replace peut remplacer les occurrences d'un modèle par une autre chaîne. De plus, vous pouvez passer une fonction à remplacer qui construira une chaîne de remplacement basée sur le modèle et les groupes trouvés.

Les expressions régulières ont des paramètres écrits après la barre oblique fermante. L'option i rend l'expression régulière insensible à la casse et l'option g la rend globale, ce qui, entre autres, oblige la méthode replace à remplacer toutes les occurrences qu'elle trouve, pas seulement la première.

Le constructeur RegExp peut être utilisé pour créer des expressions régulières à partir de chaînes.

Les régulateurs sont un outil pointu avec une poignée inconfortable. Ils simplifient grandement certaines tâches, et peuvent devenir ingérables lors de la résolution d'autres, tâches difficiles. Une partie de la capacité à utiliser des regexes consiste à être capable de résister à la tentation de les insérer dans une tâche pour laquelle ils n'ont pas été conçus.

Des exercices

Inévitablement, lors de la résolution de problèmes, vous rencontrerez des cas incompréhensibles, et vous pourrez parfois désespérer, voyant le comportement imprévisible de certaines expressions régulières. Parfois, il est utile d'étudier le comportement d'une expression régulière via un service en ligne tel que debuggex.com, où vous pouvez voir sa visualisation et la comparer avec l'effet souhaité.
Golf régulier
"Golf" dans le code s'appelle un jeu où vous devez exprimer un programme donné avec un nombre minimum de caractères. Le golf régulier est un exercice pratique d'écriture des plus petites expressions régulières possibles pour trouver un motif donné, et rien que cela.

Pour chacune des sous-chaînes, écrivez une expression régulière pour vérifier si elles sont dans la chaîne. Le régulier ne devrait trouver que ces sous-chaînes spécifiées. Ne vous souciez pas des limites des mots, sauf mention contraire. Lorsque vous obtenez une expression régulière fonctionnelle, essayez de la réduire.

voiture et chat
- pop et accessoire
- furet, ferry et ferrari
- Tout mot se terminant par ious
- Un espace suivi d'un point, d'une virgule, de deux-points ou d'un point-virgule.
- Un mot de plus de six lettres
- Mot sans lettres e

// Entrez vos expressions régulières verify(/.../, ["my car", "bad cats"], ["camper", "high art"]); vérifier(/.../, ["pop culture", "mad props"], ["plop"]); vérifier(/.../, ["ferret", "ferry", "ferrari"], ["ferrum", "transfert A"]); vérifier(/.../, ["comme c'est délicieux", "pièce spacieuse"], ["ruineux", "conscience"]); vérifier(/.../, ["mauvaise ponctuation ."], ["échapper le point"]); vérifier(/.../, ["hottentottetenten"], ["no", "hotten totten tenten"]); vérifier(/.../, ["ornithorynque rouge", "nid oscillant"], ["lit de terre", "singe apprenant"]); function verify(regexp, yes, no) ( // Ignore les exercices inachevés if (regexp.source == "...") return; yes.forEach(function(s) ( if (!regexp.test(s)) console .log("Trouvé "" + s + """); )); no.forEach(fonction(s) ( if (regexp.test(s)) console.log("Occurrence inattendue de "" + s + " ""); )); )

Les guillemets dans le texte
Disons que vous avez écrit une histoire et que vous avez utilisé des guillemets simples tout au long du dialogue. Maintenant, vous voulez remplacer les guillemets de dialogue par des guillemets doubles et laisser des guillemets simples dans les abréviations de mots comme ne sont pas.

Trouvez un modèle qui différencie ces deux utilisations des guillemets et écrivez un appel à la méthode replace qui effectue le remplacement.

Encore des chiffres
Les séquences de chiffres peuvent être trouvées avec une simple expression régulière /\d+/.

Écrivez une expression qui ne trouve que des nombres écrits dans le style JavaScript. Il doit prendre en charge un possible moins ou plus devant le nombre, un point décimal et une notation exponentielle 5e-3 ou 1E10 - encore une fois avec un plus ou moins possible. Notez également que le point ne doit pas nécessairement être précédé ou suivi de chiffres, mais le nombre ne peut pas être constitué d'un seul point. Autrement dit, .5 ou 5. sont des nombres valides, mais un point en lui-même ne l'est pas.

// Entrez une expression régulière ici. var nombre = /^...$/; // Tests : ["1", "-1", "+15", "1.55", ".5", "5.", "1.3e2", "1E-4", "1e+12"] .forEach(function(s) ( if (!number.test(s)) console.log("N'a pas trouvé "" + s + """); )); ["1a", "+-1", "1.2.3", "1+1", "1e4.5", ".5.", "1f5", "."].forEach(fonction(s) ( if (nombre.test(s)) console.log("Invalide "" + s + """); ));

Une expression régulière est un objet qui décrit un modèle de caractère. La classe RegExp en JavaScript représente des expressions régulières, et les objets des classes String et RegExp définissent des méthodes qui utilisent des expressions régulières pour effectuer des opérations de correspondance de modèles et de remplacement de texte.

Les expressions régulières sont un outil puissant pour le traitement des données entrantes. Une tâche qui nécessite un remplacement de texte ou une recherche peut être magnifiquement résolue avec cette "langue dans une langue".

Création

En JavaScript, les expressions régulières sont représentées par des objets RegExp. Les objets RegExp peuvent être créés à l'aide du constructeur RegExp(), mais le plus souvent, ils sont créés à l'aide d'une syntaxe littérale spéciale. Façons de créer :

// Utilisation d'un littéral d'expression régulière : var re = /ab+c/ ;

Les littéraux d'expression régulière entraînent la précompilation de l'expression régulière lors de l'analyse du script.

// Appel de la fonction constructeur de l'objet RegExp var re = new RegExp("ab+c");

L'utilisation du constructeur implique la compilation de l'expression régulière au moment du script. Il est nécessaire d'utiliser cette méthode si l'on sait que l'expression va changer.

Caractères spéciaux dans les expressions régulières

\ – Pour les personnages réguliers, les rend spéciaux. Par exemple, l'expression /s/ recherche simplement le caractère 's'. Et si vous mettez \ avant s, alors /\s/ représente déjà un caractère d'espacement.

^ – Indique le début des données d'entrée. Si l'indicateur de recherche multiligne ("m") est défini, il fonctionnera également au début d'une nouvelle ligne.

$ – Indique la fin des données d'entrée. Si l'indicateur de recherche multiligne est défini, il fonctionnera également à la fin de la ligne.

* – Indique la répétition de 0 fois ou plus. Par exemple, /bo*/ trouvera 'boooo' dans "A ghost booooed" et 'b' dans "A bird warbled" mais ne trouvera rien dans "A goat grunted".

+ – Indique la répétition d'une ou plusieurs fois. Équivalent à (1,). Par exemple, /a+/ trouvera 'a' dans 'candy' et tous les 'a' dans 'caaaaaaandy'.

? – Indique que l'élément peut ou non être présent.

. – (Point décimal) désigne tout caractère autre qu'un saut de ligne : \n \r \u2028 ou \u2029. (vous pouvez utiliser [\s\S] pour rechercher n'importe quel caractère, y compris les retours à la ligne).

(X)– Trouve x et se souvient. C'est ce qu'on appelle "se souvenir des parenthèses". Par exemple, /(foo)/ trouvera et se souviendra de « foo » dans « foo bar ». La sous-chaîne trouvée est stockée dans le tableau des résultats de la recherche ou dans les propriétés prédéfinies de l'objet RegExp : $1, ..., $9.

(?:X)– Trouve x, mais ne se souvient pas de ce qui a été trouvé. C'est ce qu'on appelle les "parenthèses non mémorisées". La sous-chaîne trouvée n'est pas stockée dans le tableau de résultats et les propriétés RegExp. Comme toutes les parenthèses, combinez ce qu'elles contiennent en un seul sous-modèle.

x(?=y)– Trouve x uniquement si x est suivi de y. Par exemple, /Jack(?=Sprat)/ ne trouvera 'Jack' que s'il est suivi de 'Sprat'. /Jack(?=Sprat|Frost)/ ne correspondra à 'Jack' que s'il est suivi de 'Sprat' ou 'Frost'. Cependant, ni 'Sprat' ni 'Frost' n'apparaîtront dans le résultat de la recherche.

x(?!y)– Trouve x uniquement si x n'est pas suivi de y. Par exemple, /\d+(?!\.)/ ne correspondra à un nombre que s'il n'est pas suivi d'un point décimal. /\d+(?!\.)/.exec(“3.141”) trouvera 141 mais pas 3.141.

x|y– Trouve x ou y. Par exemple, /vert|rouge/ correspondra à « vert » dans « pomme verte » et à « rouge » dans « pomme rouge ».

(n)– Un entier positif. Trouve exactement n répétitions de l'élément précédent.

(n,)– Un entier positif. Trouve n ou plusieurs occurrences d'un élément.

(n, m)– Entiers positifs. Trouver de n à m répétitions d'un élément.

- Jeu de caractères. Recherche l'un des caractères répertoriés. Vous pouvez spécifier une étendue à l'aide d'un tiret. Par exemple, est identique à .

[^xyz]– Tout caractère autre que ceux spécifiés dans le jeu. Vous pouvez également spécifier une plage. Par exemple, [^abc] est identique à [^a-c].

[\b]– Trouve un caractère de retour arrière.

\b– Trouve la limite des mots (latin).

\B– N'indique pas une limite de mot. Par exemple, /\w\Bn/ correspondra à 'on' dans "noonday" et /y\B\w/ correspondra à 'ye' dans "probablement hier".

\cX– X est une lettre de A à Z. Désigne un caractère de contrôle dans une chaîne. Par exemple, /\cM/ représente le caractère Ctrl-M.

\ré– Trouve un nombre de n'importe quel alphabet.

\RÉ– Recherche un caractère non numérique (tous les alphabets). [^0-9] est l'équivalent des chiffres réguliers.

\f,\r,\n– Caractères spéciaux correspondants saut de page, saut de ligne, saut de ligne.

\s– Correspond à n'importe quel caractère d'espace blanc, y compris les espaces, les tabulations, les nouvelles lignes et d'autres caractères d'espace blanc Unicode.

\S– Correspond à n'importe quel caractère sauf les espaces.

\t- Caractère de tabulation.

\v– Caractère de tabulation verticale.

\w– Correspond à n'importe quel caractère de mot (latin), y compris les lettres, les chiffres et les traits de soulignement. Équivalent à .

\W– Correspond à n'importe quel caractère de mot (non latin). Équivalent à [^A-Za-z0-9_].

\0 – Trouve le caractère NUL.

\xhh– Recherche le caractère avec le code hh (2 chiffres hexadécimaux).

\uhhhh– Recherche le caractère avec le code hhhh (4 chiffres hexadécimaux).

Drapeaux

Les indicateurs d'expression régulière définissent des règles de correspondance de modèles de haut niveau. Contrairement au reste de la grammaire des expressions régulières, les drapeaux ne sont pas spécifiés entre les caractères slash, mais après le second. À Javascript trois drapeaux sont pris en charge.

Drapeau je spécifie que la correspondance de modèle doit être insensible à la casse, et le drapeau g– que la recherche doit être globale, c'est-à-dire toutes les correspondances dans la chaîne doivent être trouvées. Drapeau m effectue une recherche de motif en mode multiligne. Si l'expression de chaîne recherchée contient des retours à la ligne, dans ce mode, les caractères d'ancrage ^ et $, en plus de correspondre au début et à la fin de l'expression de chaîne entière, correspondent également au début et à la fin de chaque ligne de texte. Les drapeaux peuvent être combinés dans n'importe quelle combinaison.

Méthodes de classe de chaîne

Les chaînes prennent en charge quatre méthodes utilisant des expressions régulières.

méthode de recherche ()

Elle prend une expression régulière comme argument et renvoie soit la position du premier caractère de la sous-chaîne trouvée, soit -1 si aucune correspondance n'est trouvée. Par exemple, l'appel suivant renverra 4 :

Varresult = "JavaScript".search(/script/i); // quatre

Si l'argument de la méthode search() n'est pas une expression régulière, il est d'abord converti en le passant au constructeur RegExp. La méthode search() ne prend pas en charge les recherches globales et ignore le drapeau g dans votre argumentaire.

méthode replace()

Il effectue une opération de recherche et de remplacement. Il prend une expression régulière comme premier argument et une chaîne de remplacement comme second. La méthode recherche la chaîne pour laquelle elle est appelée pour correspondre au modèle spécifié. Si l'expression régulière contient l'indicateur g, la méthode replace() remplace toutes les correspondances trouvées par la chaîne de remplacement. Sinon, il remplace uniquement la première correspondance trouvée.

méthode match()

Il prend une expression régulière comme seul argument (ou convertit son argument en une expression régulière en le passant au constructeur RegExp()) et renvoie un tableau contenant les résultats de la recherche. Si l'indicateur g est défini dans l'expression régulière, la méthode renvoie un tableau de toutes les correspondances présentes dans la chaîne. Par example:

// renvoie ["1", "2", "3"] var result = "1 plus 2 égale 3".match(/\d+/g);

Si l'expression régulière ne contient pas l'indicateur g, la méthode match() n'effectue pas de recherche globale ; il cherche juste le premier match. Cependant, match() renvoie un tableau même lorsque la méthode n'effectue pas de recherche globale. Dans ce cas, le premier élément du tableau est la sous-chaîne trouvée et tous les éléments restants sont des sous-expressions de l'expression régulière.

méthode split()

Cette méthode divise la chaîne sur laquelle elle est appelée en un tableau de sous-chaînes, en utilisant l'argument comme délimiteur. Par example:

"123 456 789".split(","); // Renvoie ["123","456","789"]

La méthode split() peut également prendre une expression régulière comme argument. Cela rend la méthode plus puissante.

Objet d'expression régulière

Le constructeur RegExp() prend un ou deux arguments de chaîne et crée un nouvel objet RegExp. Le premier argument du constructeur est une chaîne contenant le corps de l'expression régulière, c'est-à-dire le texte qui doit apparaître entre les barres obliques dans le littéral de l'expression régulière. Le deuxième argument de RegExp() peut être manquant. S'il est spécifié, il spécifie les indicateurs d'expression régulière. Ce doit être l'un des personnages g, je, m ou une combinaison de ces caractères.

Propriétés d'expression régulière

Chaque objet RegExp a cinq propriétés :

  • la source– une chaîne en lecture seule contenant le texte de l'expression régulière.
  • global– un booléen en lecture seule indiquant la présence du drapeau g dans une expression régulière.
  • ignoreCase je dans une expression régulière.
  • multiligne est un booléen en lecture seule indiquant la présence du drapeau m dans une expression régulière.
  • dernierIndex est un entier qui peut être lu et écrit. Pour les modèles de drapeaux g cette propriété contient le numéro de position dans la chaîne à laquelle la prochaine recherche doit commencer.

Méthodes RegExp

Les objets RegExp définissent deux méthodes qui effectuent une correspondance de modèle.

méthode exec()

La méthode exec() exécute l'expression régulière pour la chaîne spécifiée, c'est-à-dire recherche une correspondance dans une chaîne. Si aucune correspondance n'est trouvée, la méthode renvoie null. Cependant, si une correspondance est trouvée, elle renvoie le même tableau que le tableau renvoyé par la méthode match() pour la recherche sans l'indicateur g.

L'élément zéro du tableau contient la chaîne qui correspond à l'expression régulière, et tous les éléments suivants sont des sous-chaînes qui correspondent à toutes les sous-expressions. Contrairement à match(), la méthode exec() renvoie un tableau dont la structure ne dépend pas de la présence du drapeau dans l'expression régulière g.

Lorsque la méthode exec() est appelée une deuxième fois pour la même expression régulière, elle commence la recherche à la position de caractère spécifiée dans la propriété lastIndex. Si exec() ne trouve pas de correspondance, la propriété lastIndex est définie sur 0.

méthode d'essai

Elle prend une chaîne et renvoie true si la chaîne correspond à l'expression régulière :

Varpattern = /java/i; modèle.test("JavaScript"); // Retourne vrai

Appeler test() équivaut à appeler exec() retournant true si exec() retourne non-null. Pour cette raison, la méthode test() se comporte de la même manière que la méthode exec() lorsqu'elle est appelée sur une expression régulière globale : elle commence à rechercher la chaîne spécifiée à la position spécifiée par la propriété lastIndex, et si elle trouve une correspondance , il définit la propriété lastIndex sur le numéro de position du caractère suivant directement la correspondance trouvée.

Écrire un modèle

Un modèle d'expression régulière se compose de caractères ordinaires, tels que /abc/, ou de combinaisons de caractères ordinaires et spéciaux, tels que /ab*c/ ou /Chapter (\d+)\.\d*/. Le dernier exemple inclut des parenthèses, qui sont utilisées comme "mécanisme de mémoire". La correspondance de cette partie du motif est mémorisée pour une utilisation ultérieure.

Utiliser des modèles simples

Des modèles simples sont utilisés pour trouver des correspondances directes dans le texte. Par exemple, le modèle /abc/ correspond à une combinaison de caractères dans une chaîne uniquement lorsque les caractères « abc » apparaissent ensemble et dans le même ordre.

Cet article a couvert les bases de l'utilisation d'une expression régulière en Javascript.

Introduction

Qu'est-ce qu'une expression régulière ?

Une expression régulière JS est une séquence de caractères qui forme une règle de recherche. Cette règle peut ensuite être utilisée pour rechercher du texte ainsi que pour le remplacer. En pratique, une expression régulière peut même consister en un seul caractère, mais des modèles de recherche plus complexes sont plus courants.

En Javascript, les expressions régulières sont aussi des objets. Ce sont des modèles utilisés pour faire correspondre des séquences de caractères dans des chaînes. Ils sont utilisés dans les méthodes exec() et test() de l'objet RegExp, et dans les méthodes match() , replace() , search et split() de l'objet String.

Exemple

var modèle = /exemple/i

/exemple/i est une expression régulière. exemple est un modèle ( à utiliser dans la recherche). i est un modificateur indiquant la sensibilité à la casse.

Préparation d'une expression régulière

Les expressions régulières JS consistent en un modèle et un modificateur. La syntaxe ressemblera à ceci :

/motif/modificateurs ;

Le modèle définit la règle de recherche. Il se compose de caractères simples comme /abc/ ou d'une combinaison de caractères simples et spéciaux : /abc/ ou /Chapter (d+).d/ .

Tableau des modèles

Les modificateurs vous permettent de rendre les requêtes sensibles à la casse, globales, etc. Ils sont utilisés pour effectuer des recherches sensibles à la casse ainsi que des recherches globales.

Tableau des modificateurs


Nous sommes maintenant prêts à appliquer les expressions régulières JS. Il existe deux manières principales de procéder : en utilisant un objet d'expression régulière ou en utilisant une expression régulière sur une chaîne.

Utilisation de l'objet d'expression régulière

Créer un objet d'expression régulière

Cet objet décrit un modèle de personnage. Il est utilisé pour la correspondance de motifs. Il existe deux façons de construire un objet d'expression régulière.

Méthode 1 : Utilisation d'un littéral d'expression régulière composé d'un modèle entouré de barres obliques, comme ceci :

varreg = /ab+c/;

Les littéraux d'expressions régulières déclenchent la précompilation des expressions régulières lorsque le script est analysé. Si l'expression régulière est constante, utilisez-la pour augmenter les performances.

Méthode 2 : En appelant la fonction constructeur de l'objet RegExp, par exemple :

varreg = new RegExp("ab+c");

L'utilisation du constructeur vous permet de compiler l'expression régulière JS au moment du script. Utilisez cette méthode si l'expression régulière va changer ou si vous ne connaissez pas le modèle à l'avance. Par exemple, si vous recevez des informations d'un utilisateur qui saisit une requête de recherche.

Méthodes d'objet d'expression régulière

Familiarisons-nous avec quelques méthodes courantes de l'objet d'expression régulière :

  • compiler() ( obsolète dans la version 1.5) - compile une expression régulière ;
  • exec() - Effectue une correspondance sur une chaîne. Renvoie la première correspondance ;
  • test() - effectue une correspondance sur une chaîne. Renvoie vrai ou faux ;
  • toString() - renvoie la valeur de chaîne de l'expression régulière.

Exemples

Utiliser test()

La méthode test() est une expression régulière de l'objet RegExp. Il recherche une chaîne de modèle et renvoie vrai ou faux en fonction du résultat. L'exemple d'expression régulière JS suivant montre comment une chaîne est recherchée pour le caractère " e”:

varpatt = /e/; patt.test("Les meilleures choses au monde sont gratuites!");

Puisqu'ici dans la ligne il y a " e”, le résultat de ce code sera true .

Les expressions régulières n'ont pas du tout besoin d'être placées dans une variable. La même requête peut être effectuée sur une seule ligne :

/e/.test("Les meilleures choses au monde sont gratuites!");

Utiliser exec()

Il recherche la chaîne en fonction de la règle de recherche donnée et renvoie le texte trouvé. Si aucune correspondance n'a été trouvée, le résultat est null .

Regardons la méthode en action, en utilisant l'exemple du même symbole " e”:

/e/.exec("Les meilleures choses au monde sont gratuites!");

Puisque la ligne contient " e”, le résultat de ce code sera .e .

Application d'une expression régulière à une chaîne

En Javascript, ces expressions peuvent également être utilisées avec deux méthodes sur l'objet String : search() et replace() . Ils sont nécessaires pour effectuer une recherche et un remplacement dans le texte.

  • Méthode search() - utilise une expression pour trouver une correspondance et renvoie des informations sur l'emplacement de la correspondance ;
  • La méthode replace() renvoie une chaîne modifiée avec le modèle remplacé.

Exemples

Utilisation d'une expression régulière JS pour effectuer une recherche sensible à la casse pour la phrase " w3schools" en ligne:

varstr = "Visiter W3Schools" ; var n = str.search(/w3schools/i);

Le résultat en n sera 6.

La méthode de recherche prend également une chaîne comme argument. L'argument de chaîne sera converti en une expression régulière :

Utiliser une chaîne pour rechercher la phrase " W3schools" en ligne:

var str = "Visitez W3Schools !" ; varn = str.search("W3Schools");

Application d'une expression régulière JS sensible à la casse pour remplacer " Microsoft" au " W3Schools" en ligne:

var str = "Visitez Microsoft !" ; var res = str.replace(/microsoft/i, "W3Schools");

En conséquence, nous obtenons : « Visitez W3Schools ! ".

La méthode replace() accepte également une chaîne de recherche :

var str = "Visitez Microsoft !" ; var res = str.replace("Microsoft", "W3Schools");

Traduction de l'article " Utiliser une expression régulière en Javascript» a été préparé par une sympathique équipe de projet

Expressions régulières

Expression régulière est un objet qui décrit un modèle de personnage. La classe RegExp en JavaScript représente des expressions régulières, et les objets des classes String et RegExp définissent des méthodes qui utilisent des expressions régulières pour effectuer des opérations de correspondance de modèles et de remplacement de texte. La grammaire des expressions régulières en JavaScript contient un sous-ensemble assez complet de la syntaxe des expressions régulières utilisée dans Perl 5, donc si vous êtes familier avec Perl, vous devriez être capable d'écrire facilement des modèles dans les programmes JavaScript.

Les fonctionnalités des expressions régulières Perl qui ne sont pas prises en charge dans ECMAScript incluent les drapeaux s (mode ligne unique) et x (syntaxe étendue) ; les séquences d'échappement \a, \e, \l, \u, \L, \U, \E, \Q, \A, \Z, \z et \G, et d'autres constructions étendues commençant par (?.

Définition des expressions régulières

En JavaScript, les expressions régulières sont représentées par des objets. Expression régulière. Les objets RegExp peuvent être créés à l'aide du constructeur RegExp(), mais le plus souvent, ils sont créés à l'aide d'une syntaxe littérale spéciale. Tout comme les littéraux de chaîne sont spécifiés sous forme de caractères entre guillemets, les littéraux d'expressions régulières sont spécifiés sous forme de caractères entre guillemets (/). Ainsi, le code JavaScript peut contenir des lignes similaires à ceci :

Varpattern = /s$/;

Cette ligne crée un nouvel objet RegExp et l'affecte à la variable de modèle. Cet objet RegExp recherche toutes les chaînes qui se terminent par "s". La même expression régulière peut être définie à l'aide du constructeur RegExp() :

Varpattern = new RegExp("s$");

Une spécification de modèle d'expression régulière se compose d'une séquence de caractères. La plupart des caractères, y compris tous les caractères alphanumériques, décrivent littéralement les caractères qui doivent être présents. Autrement dit, l'expression régulière /java/ correspond à toutes les chaînes contenant la sous-chaîne "java".

Les autres caractères des expressions régulières ne sont pas destinés à être recherchés pour leurs équivalents exacts, mais ont une signification particulière. Par exemple, l'expression régulière /s$/ contient deux caractères. Le premier caractère s indique une recherche d'un caractère littéral. Le second, $, est un métacaractère spécial qui marque la fin d'une ligne. Cette expression régulière correspond donc à toute chaîne se terminant par s.

Les sections suivantes décrivent les différents caractères et métacaractères utilisés dans les expressions régulières JavaScript.

Symboles littéraux

Comme indiqué précédemment, tous les caractères alphabétiques et les chiffres des expressions régulières se correspondent. La syntaxe des expressions régulières de JavaScript prend également en charge la possibilité de spécifier certains caractères non alphabétiques à l'aide de séquences d'échappement commençant par une barre oblique inverse (\). Par exemple, la séquence \n correspond au caractère de saut de ligne. Ces caractères sont listés dans le tableau ci-dessous :

Certains signes de ponctuation ont une signification particulière dans les expressions régulières :

^ $ . * + ? = ! : | \ / () { } -

La signification de ces symboles est expliquée dans les sections suivantes. Certains d'entre eux n'ont une signification particulière que dans certains contextes d'expressions régulières, tandis que dans d'autres contextes, ils sont pris littéralement. Cependant, en général, pour inclure littéralement l'un de ces caractères dans une expression régulière, vous devez le faire précéder d'une barre oblique inverse. D'autres caractères, tels que les guillemets et @, n'ont pas de signification particulière et se correspondent simplement dans les expressions régulières.

Si vous ne vous souvenez pas exactement quel caractère doit être précédé d'un \, vous pouvez sans risque placer une barre oblique inverse avant l'un des caractères. Cependant, gardez à l'esprit que de nombreuses lettres et chiffres prennent des significations particulières avec la barre oblique, donc les lettres et chiffres que vous recherchez littéralement ne doivent pas être précédés d'un \. Pour inclure le caractère antislash lui-même dans l'expression régulière, vous devez évidemment le faire précéder d'un autre caractère antislash. Par exemple, l'expression régulière suivante correspond à toute chaîne contenant une barre oblique inverse : /\\/.

Classes de personnages

Les caractères littéraux individuels peuvent être combinés en classes de caractères en les plaçant entre crochets. Une classe de caractères correspond à n'importe quel caractère contenu dans cette classe. Par conséquent, l'expression régulière // correspond à l'un des caractères a, b ou c.

Des classes de caractères inversées peuvent également être définies, correspondant à tout caractère autre que ceux indiqués entre parenthèses. La classe de caractères inversée est spécifiée par le caractère ^ comme premier caractère après la parenthèse gauche. L'expression régulière /[^abc]/ correspond à tout caractère autre que a, b ou c. Dans les classes de caractères, une plage de caractères peut être spécifiée avec un trait d'union. Tous les caractères latins minuscules sont recherchés à l'aide de l'expression //, et toute lettre ou chiffre du jeu de caractères latins peut être trouvé à l'aide de l'expression //.

Certaines classes de caractères sont utilisées particulièrement fréquemment, c'est pourquoi la syntaxe des expressions régulières en JavaScript inclut des caractères spéciaux et des séquences d'échappement pour les désigner. Par exemple, \s correspond aux espaces, aux tabulations et à tous les caractères d'espacement du jeu Unicode, et \S correspond à tous les caractères non blancs du jeu Unicode.

Le tableau ci-dessous répertorie ces caractères spéciaux et la syntaxe des classes de caractères. (Notez que certaines des séquences d'échappement des classes de caractères correspondent uniquement aux caractères ASCII et ne sont pas étendues pour fonctionner avec les caractères Unicode. Vous pouvez définir explicitement vos propres classes de caractères Unicode, par exemple /[\u0400-\u04FF]/ correspond à n'importe quel caractère cyrillique. )

Classes de caractères d'expressions régulières JavaScript
Symbole Conformité
[...] N'importe lequel des caractères entre parenthèses
[^...] N'importe lequel des caractères non entre parenthèses
. Tout caractère autre qu'un retour à la ligne ou un autre délimiteur de chaîne Unicode
\w N'importe quel caractère de texte ASCII. De manière équivalente
\W Tout caractère qui n'est pas un caractère de texte ASCII. Équivalent à [^a-zA-Z0-9_]
\s Tout caractère d'espacement du jeu Unicode
\S Tout caractère autre qu'un espace blanc du jeu de caractères Unicode. Notez que \w et \S ne sont pas identiques
\ré Tous les chiffres ASCII. De manière équivalente
\RÉ Tout caractère autre que les chiffres ASCII. Équivalent à [^0-9]
[\b] caractère littéral de retour arrière

Notez que les séquences d'échappement de caractères spéciaux de classe peuvent être placées entre crochets. \s correspond à n'importe quel caractère d'espacement et \d correspond à n'importe quel chiffre, donc /[\s\d]/ correspond à n'importe quel caractère ou chiffre d'espacement.

Répétition

Avec la connaissance de la syntaxe des expressions régulières acquise jusqu'à présent, nous pouvons décrire un nombre à deux chiffres comme /\d\d/ ou un nombre à quatre chiffres comme /\d\d\d\d/, mais nous ne pouvons pas, par exemple , décrire un nombre composé de n'importe quel nombre de chiffres ou d'une chaîne de trois lettres suivies d'un chiffre facultatif. Ces modèles plus complexes utilisent la syntaxe des expressions régulières pour spécifier combien de fois il peut se répéter. élément donné expression régulière.

Les symboles indiquant la répétition suivent toujours le modèle auquel ils s'appliquent. Certains types de répétitions sont utilisés assez souvent et il existe des symboles spéciaux pour ces cas. Par exemple, + correspond à une ou plusieurs instances du modèle précédent. Le tableau suivant est un résumé de la syntaxe de répétition :

Les lignes suivantes montrent quelques exemples :

ModèleVar = /\d(2,4)/ ; // Correspond à un nombre contenant deux à quatre chiffres pattern = /\w(3)\d?/; // Correspond exactement à trois caractères de mot et à un modèle de chiffre facultatif = /\s+java\s+/ ; // Correspond au mot "java" avec un ou plusieurs espaces // avant et après motif = /[^(]*/; // Correspond à zéro ou plusieurs caractères autres que la parenthèse ouvrante

Soyez prudent lorsque vous utilisez les caractères de répétition * et ?. Ils peuvent correspondre à l'absence de motif qu'ils précèdent, et donc à l'absence de caractères. Par exemple, l'expression régulière /a*/ correspond à la chaîne "bbbb" car elle ne contient pas le caractère a.

Les caractères de répétition répertoriés dans le tableau correspondent au nombre maximal de répétitions possibles, ce qui garantit la recherche des parties suivantes de l'expression régulière. Nous disons qu'il s'agit d'une répétition "gourmande". Il est également possible de mettre en œuvre la répétition de manière « non gourmande ». Il suffit de spécifier un point d'interrogation après le caractère (ou les caractères) de répétition : ??, +?, *? ou même (1,5)?.

Par exemple, l'expression régulière /a+/ correspond à une ou plusieurs instances de la lettre a. Appliqué à la chaîne "aaa", il correspond aux trois lettres. D'autre part, /a+?/ correspond à une ou plusieurs occurrences de la lettre a et sélectionne le moins de caractères possible. Appliqué à la même chaîne, ce modèle ne correspond qu'à la première lettre a.

La répétition « non gourmande » ne donne pas toujours le résultat escompté. Considérez le motif /a+b/ qui correspond à un ou plusieurs a suivis d'un b. Pour la chaîne "aaab", il correspond à la chaîne entière.

Vérifions maintenant la version "non gourmande" de /a+?b/. On pourrait penser qu'il doit correspondre à un b précédé d'un seul a. S'il est appliqué à la même chaîne, "aaab" devrait correspondre à un seul a et au dernier b. Cependant, en fait, la chaîne entière correspond à ce modèle, comme dans le cas de la version "gourmande". En effet, la recherche de modèle d'expression régulière est effectuée en trouvant la première position dans la chaîne à partir de laquelle une correspondance devient possible. Puisqu'une correspondance est possible à partir du premier caractère de la chaîne, les correspondances plus courtes à partir des caractères suivants ne sont même pas prises en compte.

Alternatives, regroupement et liens

La grammaire des expressions régulières comprend des caractères spéciaux pour définir des alternatives, regrouper des sous-expressions et des références à des sous-expressions précédentes. Symbole de la barre verticale | sert à séparer les alternatives. Par exemple, /ab|cd|ef/ correspond soit à la chaîne "ab", soit à la chaîne "cd", soit à la chaîne "ef" et le modèle /\d(3)|(4)/ correspond soit à trois chiffres soit à quatre minuscules lettres.

Notez que les alternatives sont traitées de gauche à droite jusqu'à ce qu'une correspondance soit trouvée. Si une correspondance est trouvée avec l'alternative de gauche, l'alternative de droite est ignorée, même si une "meilleure" correspondance peut être obtenue. Ainsi, lorsque /a|ab/ est appliqué à la chaîne "ab", il ne correspondra qu'au premier caractère.

Les parenthèses ont plusieurs significations dans les expressions régulières. L'un d'eux est le regroupement. éléments individuels en une seule sous-expression, de sorte que les éléments lors de l'utilisation des caractères spéciaux |, *, +, ? et les autres sont traités comme un seul. Par exemple, le modèle /java(script)?/ correspond au mot « java » suivi du mot facultatif « script », et /(ab|cd)+|ef)/ correspond soit à la chaîne « ef », soit à un ou plusieurs répétitions d'une des chaînes "ab" ou "cd".

Une autre utilisation des parenthèses dans les expressions régulières consiste à définir des sous-modèles dans un modèle. Lorsqu'une correspondance d'expression régulière est trouvée dans la chaîne cible, la partie de la chaîne cible qui correspond à un sous-modèle particulier entre parenthèses peut être extraite.

Supposons que vous vouliez trouver une ou plusieurs lettres minuscules suivies d'un ou plusieurs chiffres. Vous pouvez utiliser le motif /+\d+/ pour cela. Mais supposons également que nous ne voulions que les chiffres à la fin de chaque match. Si nous plaçons cette partie du modèle entre parenthèses (/+(\d+)/), alors nous pouvons extraire des nombres de toutes les correspondances que nous trouvons. Comment cela est fait sera décrit ci-dessous.

En rapport avec cela, il existe une autre utilisation des sous-expressions entre parenthèses pour faire référence aux sous-expressions de la partie précédente de la même expression régulière. Ceci est réalisé en spécifiant un ou plusieurs chiffres après le caractère \. Les nombres font référence à la position de la sous-expression entre parenthèses dans l'expression régulière. Par exemple, \1 fait référence à la première sous-expression et \3 à la troisième. Notez que les sous-expressions peuvent être imbriquées, de sorte que la position de la parenthèse gauche est utilisée dans le décompte. Par exemple, dans l'expression régulière suivante, la référence à la sous-expression imbriquée (script) ressemblera à \2 :

/(ava(script)?)\sis\s(fun\w*)/

La référence à la sous-expression précédente ne pointe pas vers le modèle de cette sous-expression, mais vers le texte trouvé qui correspond à ce modèle. Par conséquent, les références peuvent être utilisées pour imposer une contrainte qui sélectionne les parties d'une chaîne contenant exactement les mêmes caractères. Par exemple, l'expression régulière suivante correspond à zéro ou plusieurs caractères entre guillemets simples ou doubles. Cependant, il n'est pas nécessaire que les guillemets ouvrants et fermants correspondent (c'est-à-dire que les deux guillemets soient simples ou doubles) :

/[""][^""]*[""]/

Nous pouvons exiger des devis correspondant à cette référence :

Ici, \1 correspond à la première correspondance de sous-expression. Dans cet exemple, le lien impose une contrainte exigeant que la citation de fermeture corresponde à la citation d'ouverture. Cette expression régulière n'autorise pas les guillemets simples à l'intérieur des guillemets doubles, et vice versa.

Il est également possible de regrouper des éléments dans une expression régulière sans créer de référence numérotée à ces éléments. Au lieu de simplement regrouper des éléments entre (et), commencez le groupe par des caractères (?: et terminez-le par un caractère). Considérez, par exemple, le modèle suivant :

/(ava(?:script)?)\sis\s(fun\w*)/

Ici, la sous-expression (?:script) n'est nécessaire que pour le regroupement, de sorte que le caractère de répétition ? puisse être appliqué au groupe. Ces parenthèses modifiées ne créent pas de lien, donc \2 dans cette expression régulière fait référence au texte qui correspond au modèle (fun\w*).

Le tableau suivant répertorie les opérateurs select-from-alternatives, de regroupement et de référencement dans les expressions régulières :

Caractères d'expression régulière sélectionnés parmi des alternatives, des regroupements et des liens JavaScript
Symbole Sens
| Alternative. Correspond à la sous-expression de gauche ou à la sous-expression de droite.
(...) Regroupement. Regroupe les éléments en une seule entité qui peut être utilisée avec *, +, ?, | etc. Se souvient également des caractères correspondant à ce groupe pour une utilisation dans les liens suivants.
(?:...) Regroupement uniquement. Regroupe les éléments ensemble, mais ne se souvient pas des caractères correspondant à ce groupe.
\Numéro Correspond aux mêmes caractères qui ont été trouvés lors de la comparaison avec le numéro de groupe. Les groupes sont des sous-expressions entre parenthèses (éventuellement imbriquées). Les numéros de groupe sont attribués en comptant les parenthèses gauches de gauche à droite. Les groupes formés de caractères (?:) ne sont pas numérotés.

Spécification d'une position de correspondance

Comme décrit précédemment, de nombreux éléments d'une expression régulière correspondent à un seul caractère dans une chaîne. Par exemple, \s correspond à un caractère d'espacement. D'autres éléments des expressions régulières correspondent aux positions entre les caractères, pas les caractères eux-mêmes. Par exemple, \b correspond à une limite de mot - une limite entre \w (un caractère de texte ASCII) et \W (un caractère non textuel), ou une limite entre un caractère de texte ASCII et le début ou la fin d'une ligne.

Les éléments tels que \b ne définissent aucun caractère qui doit être présent dans la chaîne correspondante, mais ils définissent des positions valides pour la correspondance. Ces éléments sont parfois appelés éléments d'ancrage d'expression régulière car ils ancrent le modèle à une position spécifique dans la chaîne. Plus souvent que d'autres, des éléments d'ancrage tels que ^ et $ sont utilisés, qui ancrent les motifs au début et à la fin de la ligne, respectivement.

Par exemple, le mot "JavaScript" sur une ligne qui lui est propre peut être mis en correspondance avec l'expression régulière /^JavaScript$/. Pour trouver un seul mot "Java" (plutôt qu'un préfixe, par exemple dans le mot "JavaScript"), vous pouvez essayer d'utiliser le modèle /\sJava\s/, qui nécessite un espace avant et après le mot.

Mais cette solution pose deux problèmes. Premièrement, il ne trouvera le mot "Java" que s'il est entouré d'espaces des deux côtés, et ne le trouvera pas au début ou à la fin de la chaîne. Deuxièmement, lorsque ce modèle correspond, la chaîne qu'il renvoie contiendra des espaces de début et de fin, ce qui n'est pas exactement ce que nous voulons. Ainsi, au lieu d'un modèle qui correspond aux caractères d'espacement \s, nous utiliserons un modèle (ou ancre) qui correspond aux limites de mots \b. L'expression suivante sera obtenue : /\bJava\b/.

L'élément d'ancrage \B correspond à une position qui n'est pas une limite de mot. C'est-à-dire que le modèle /\Bcript/ correspondra aux mots "JavaScript" et "postscript" et ne correspondra pas aux mots "script" ou "Scripting".

Les expressions régulières arbitraires peuvent également servir de conditions d'ancrage. Placer une expression entre les caractères (?= et) la transforme en une correspondance anticipée pour les caractères suivants, nécessitant que ces caractères correspondent au modèle spécifié mais ne soient pas inclus dans la chaîne de correspondance.

Par exemple, pour faire correspondre le nom d'un langage de programmation courant suivi de deux-points, vous pouvez utiliser l'expression /ava(script)?(?=\:)/. Ce modèle correspond au mot "JavaScript" dans la chaîne "JavaScript : The Definitive Guide", mais il ne correspondra pas au mot "Java" dans la chaîne "Java in a Nutshell" car il n'est pas suivi de deux-points.

Si vous entrez la condition (?!, il s'agira alors d'un test d'anticipation négatif pour les caractères suivants, nécessitant que les caractères suivants ne correspondent pas au modèle spécifié. Par exemple, le modèle /Java(?!Script)(\w *)/ correspond à la sous-chaîne "Java", suivie de lettre capitale et n'importe quel nombre Caractères de texte ASCIIà condition que la sous-chaîne "Java" ne soit pas suivie de la sous-chaîne "Script". Il correspondra à la chaîne "JavaBeans" mais pas à la chaîne "Javanese", correspondra à la chaîne "JavaScript" mais pas aux chaînes "JavaScript" ou "JavaScripter".

Le tableau ci-dessous répertorie les caractères d'ancrage dans les expressions régulières :

Ancres d'expression régulière
Symbole Sens
^ Correspond au début d'une expression de chaîne ou au début d'une chaîne dans une recherche multiligne.
$ Correspond à la fin d'une expression de chaîne ou à la fin d'une chaîne dans une recherche multiligne.
\b Correspond à une limite de mot, c'est-à-dire correspond à la position entre le caractère \w et le caractère \W, ou entre le caractère \w et le début ou la fin de la chaîne. (Notez cependant que [\b] correspond à un caractère de retour arrière.)
\B Correspond à une position qui n'est pas une limite de mot.
(?=p) Vérification anticipée positive pour les caractères suivants. Nécessite que les caractères suivants correspondent au modèle p, mais n'inclut pas ces caractères dans la chaîne trouvée.
(?!p) Vérification anticipée négative pour les caractères suivants. Nécessite que les caractères suivants ne correspondent pas au modèle p.

Drapeaux

Et un dernier élément de la grammaire des expressions régulières. Les indicateurs d'expression régulière définissent des règles de correspondance de modèles de haut niveau. Contrairement au reste de la grammaire des expressions régulières, les drapeaux ne sont pas spécifiés entre les caractères slash, mais après le second. Le langage JavaScript prend en charge trois drapeaux.

drapeau je spécifie que la recherche de modèle doit être insensible à la casse, et g drapeau- que la recherche doit être globale, c'est-à-dire toutes les correspondances dans la chaîne doivent être trouvées. drapeau m effectue une recherche de motif en mode multiligne. Si l'expression de chaîne recherchée contient des retours à la ligne, dans ce mode, les caractères d'ancrage ^ et $, en plus de correspondre au début et à la fin de l'expression de chaîne entière, correspondent également au début et à la fin de chaque ligne de texte. Par exemple, le modèle /java$/im correspond à la fois à "java" et à "Java\nis fun".

Ces drapeaux peuvent être combinés dans n'importe quelle combinaison. Par exemple, pour rechercher la première occurrence du mot "java" (ou "Java", "JAVA", etc.) sans tenir compte de la casse, vous pouvez utiliser l'expression régulière non sensible à la casse /\bjava\b/ je. Et pour trouver toutes les occurrences de ce mot dans une chaîne, vous pouvez ajouter le drapeau g: /\bjava\b/gi.

Méthodes de classe de chaîne pour la correspondance de modèles

Jusqu'à présent, nous avons discuté de la grammaire des expressions régulières générées, mais nous n'avons pas examiné comment ces expressions régulières peuvent réellement être utilisées dans les scripts JavaScript. Dans cette section, nous aborderons les méthodes sur l'objet String qui utilisent des expressions régulières pour la correspondance de modèles ainsi que pour la recherche et le remplacement. Et puis nous continuerons à parler de correspondance de modèle avec des expressions régulières en examinant l'objet RegExp, ses méthodes et ses propriétés.

Les chaînes prennent en charge quatre méthodes utilisant des expressions régulières. La plus simple est la méthode recherche(). Elle prend une expression régulière comme argument et renvoie soit la position du premier caractère de la sous-chaîne trouvée, soit -1 si aucune correspondance n'est trouvée. Par exemple, l'appel suivant renverra 4 :

Varresult = "JavaScript".search(/script/i); // quatre

Si l'argument de la méthode search() n'est pas une expression régulière, il est d'abord converti en le passant au constructeur RegExp. La méthode search() ne prend pas en charge les recherches globales et ignore le drapeau g dans son argument.

Méthode remplacer() effectue une opération de recherche et de remplacement. Il prend une expression régulière comme premier argument et une chaîne de remplacement comme second. La méthode recherche la chaîne pour laquelle elle est appelée pour correspondre au modèle spécifié.

Si l'expression régulière contient l'indicateur g, la méthode replace() remplace toutes les correspondances trouvées par la chaîne de remplacement. Sinon, il remplace uniquement la première correspondance trouvée. Si le premier argument de la méthode replace() est une chaîne et non une expression régulière, alors la méthode effectue une recherche littérale de la chaîne, plutôt que de la convertir en une expression régulière à l'aide du constructeur RegExp(), comme search() méthode le fait.

Par exemple, nous pouvons utiliser la méthode replace() pour mettre uniformément en majuscule le mot "JavaScript" pour une ligne entière de texte :

// Quelle que soit la casse des caractères, on remplace le mot dans la casse souhaitée var result = "javascript".replace(/JavaScript/ig, "JavaScript");

La méthode replace() est plus puissante que ne le suggère cet exemple. Rappelez-vous que les sous-expressions entre parenthèses dans une expression régulière sont numérotées de gauche à droite et que l'expression régulière mémorise le texte qui correspond à chacune des sous-expressions. Si la chaîne de remplacement contient un signe $ suivi d'un nombre, la méthode replace() remplace ces deux caractères par le texte qui correspond à la sous-expression spécifiée. C'est une fonctionnalité très utile. Nous pouvons l'utiliser, par exemple, pour remplacer les guillemets droits dans une chaîne par des guillemets typographiques qui imitent les caractères ASCII :

// Un guillemet est un guillemet suivi d'un nombre quelconque de caractères // autres que les guillemets (nous nous en souvenons), ces caractères // sont suivis d'un autre guillemet var quote = /"([^"]*)"/g; / / Remplacez les guillemets droits par des typographiques et laissez "$1" inchangé // Citez le contenu stocké dans $1 var text = ""JavaScript" est un langage de programmation interprété."; var result = text.replace(quote, ""$1"") ; // "JavaScript" est un langage de programmation interprété.

Une chose importante à noter est que le deuxième argument de replace() peut être une fonction qui calcule dynamiquement la chaîne de remplacement.

Méthode correspondre() est la plus générale des méthodes de classe String qui utilisent des expressions régulières. Il prend une expression régulière comme seul argument (ou convertit son argument en une expression régulière en le passant au constructeur RegExp()) et renvoie un tableau contenant les résultats de la recherche. Si l'indicateur g est défini dans l'expression régulière, la méthode renvoie un tableau de toutes les correspondances présentes dans la chaîne. Par example:

// renvoie ["1", "2", "3"] var result = "1 plus 2 égale 3".match(/\d+/g);

Si l'expression régulière ne contient pas l'indicateur g, la méthode match() n'effectue pas de recherche globale ; il cherche juste le premier match. Cependant, match() renvoie un tableau même lorsque la méthode n'effectue pas de recherche globale. Dans ce cas, le premier élément du tableau est la sous-chaîne trouvée et tous les éléments restants sont des sous-expressions de l'expression régulière. Par conséquent, si match() renvoie un tableau arr, alors arr contiendra la chaîne entière trouvée, arr la sous-chaîne correspondant à la première sous-expression, et ainsi de suite. Faisant un parallèle avec la méthode replace(), nous pouvons dire que arr[n] est rempli avec le contenu de $n.

Par exemple, examinez le code suivant qui analyse une URL :

URL de la variable = /(\w+):\/\/([\w.]+)\/(\S*)/ ; var text = "Visitez notre site http://www..php"; var result = text match(url); if (result != null) ( var fullurl = result; // Contient "http://www..php" var protocol = result; // Contient "http" var host = result; // Contient "www..php ")

Notez que pour une expression régulière qui n'a pas l'indicateur de recherche globale g défini, la méthode match() renvoie la même valeur que la méthode exec() de l'expression régulière : le tableau renvoyé a des propriétés d'index et d'entrée, comme décrit dans la discussion de exec( ) ci-dessous.

La dernière méthode de l'objet String qui utilise des expressions régulières est diviser(). Cette méthode divise la chaîne sur laquelle elle est appelée en un tableau de sous-chaînes, en utilisant l'argument comme délimiteur. Par example:

"123 456 789".split(","); // Renvoie ["123","456","789"]

La méthode split() peut également prendre une expression régulière comme argument. Cela rend la méthode plus puissante. Par exemple, vous pouvez spécifier un délimiteur qui autorise un nombre arbitraire d'espaces blancs des deux côtés :

"1, 2, 3 , 4 , 5".split(/\s*,\s*/); // Renvoie ["1","2","3","4","5"]

Objet d'expression régulière

Comme mentionné, les expressions régulières sont représentées comme des objets RegExp. En plus du constructeur RegExp(), les objets RegExp prennent en charge trois méthodes et plusieurs propriétés.

Le constructeur RegExp() prend un ou deux arguments de chaîne et crée un nouvel objet RegExp. Le premier argument du constructeur est une chaîne contenant le corps de l'expression régulière, c'est-à-dire le texte qui doit apparaître entre les barres obliques dans le littéral de l'expression régulière. Notez que les littéraux de chaîne et les expressions régulières utilisent le caractère \ pour désigner les séquences d'échappement. Par conséquent, lorsque vous transmettez une expression régulière en tant que littéral de chaîne au constructeur RegExp(), vous devez remplacer chaque caractère \ par une paire de caractères \\.

Le deuxième argument de RegExp() peut être manquant. S'il est spécifié, il spécifie les indicateurs d'expression régulière. Il doit s'agir de l'un des caractères g, i, m ou d'une combinaison de ces caractères. Par example:

// Trouve tous les nombres à cinq chiffres dans une chaîne. Notez // l'utilisation des caractères \\ dans cet exemple var code postal = new RegExp("\\d(5)", "g");

Le constructeur RegExp() est utile lorsqu'une expression régulière est générée dynamiquement et ne peut donc pas être représentée à l'aide de la syntaxe littérale d'expression régulière. Par exemple, pour rechercher une chaîne saisie par l'utilisateur, vous devez créer une expression régulière au moment de l'exécution à l'aide de RegExp().

Propriétés d'expression régulière

Chaque objet RegExp a cinq propriétés. Biens la source- une chaîne en lecture seule contenant le texte de l'expression régulière. Biens global est une valeur booléenne en lecture seule qui spécifie la présence de l'indicateur g dans l'expression régulière. Biens ignoreCase est un booléen en lecture seule qui spécifie si l'indicateur i est présent dans l'expression régulière. Biens multiligne est un booléen en lecture seule qui spécifie si l'indicateur m est présent dans l'expression régulière. Et la dernière propriété dernierIndex est un entier en lecture/écriture. Pour les modèles avec le drapeau g, cette propriété contient le numéro de la position dans la chaîne à laquelle la prochaine recherche doit commencer. Comme décrit ci-dessous, il est utilisé par les méthodes exec() et test().

Méthodes RegExp

Les objets RegExp définissent deux méthodes qui effectuent une correspondance de modèle ; elles se comportent de la même manière que les méthodes de la classe String décrites ci-dessus. La méthode principale de la classe RegExp utilisée pour la correspondance de modèle est exec(). Elle est similaire à la méthode match() de la classe String mentionnée, sauf qu'il s'agit d'une méthode de la classe RegExp qui prend une chaîne comme argument, plutôt qu'une méthode de la classe String qui prend un argument RegExp.

La méthode exec() exécute l'expression régulière pour la chaîne spécifiée, c'est-à-dire recherche une correspondance dans une chaîne. Si aucune correspondance n'est trouvée, la méthode renvoie null. Cependant, si une correspondance est trouvée, elle renvoie le même tableau que celui renvoyé par la méthode match() pour une recherche sans l'indicateur g. L'élément zéro du tableau contient la chaîne qui correspond à l'expression régulière, et tous les éléments suivants sont des sous-chaînes qui correspondent à toutes les sous-expressions. De plus, la propriété indice contient le numéro de position du caractère par lequel commence le fragment correspondant et la propriété contribution fait référence à la chaîne recherchée.

Contrairement à match(), la méthode exec() renvoie un tableau dont la structure ne dépend pas de la présence du drapeau g dans l'expression régulière. Permettez-moi de vous rappeler que lors du passage d'une expression régulière globale, la méthode match() renvoie un tableau des correspondances trouvées. Et exec() renvoie toujours une correspondance, mais fournit à ce sujet informations complètes. Lorsque exec() est appelée sur une expression régulière contenant l'indicateur g, la méthode définit la propriété lastIndex de l'objet expression régulière sur le numéro de position du caractère suivant immédiatement la sous-chaîne correspondante.

Lorsque la méthode exec() est appelée une deuxième fois pour la même expression régulière, elle commence la recherche à la position de caractère spécifiée dans la propriété lastIndex. Si exec() ne trouve pas de correspondance, la propriété lastIndex est définie sur 0. (Vous pouvez également définir lastIndex sur zéro à tout moment, ce que vous devez faire dans tous les cas où la recherche se termine avant que la dernière correspondance d'une ligne ne soit trouvée , et la recherche commence sur une autre chaîne avec le même objet RegExp.) Ce comportement spécial vous permet d'appeler exec() à plusieurs reprises pour itérer sur toutes les correspondances de l'expression régulière dans la chaîne. Par example:

ModèleVar = /Java/g; var text = "JavaScript est plus amusant que Java !"; varrésultat ; while((result = pattern.exec(text)) != null) ( console.log("Found "" + result + """ + " at position " + result.index + "; la prochaine recherche commencera à " + modèle .lastIndex); )

Une autre méthode d'objet RegExp - test(), ce qui est beaucoup méthode plus simple exec(). Elle prend une chaîne et renvoie true si la chaîne correspond à l'expression régulière :

Varpattern = /java/i; modèle.test("JavaScript"); // Retourne vrai

Appeler test() équivaut à appeler exec() retournant true si exec() retourne non-null. Pour cette raison, la méthode test() se comporte de la même manière que la méthode exec() lorsqu'elle est appelée sur une expression régulière globale : elle commence à rechercher la chaîne spécifiée à la position spécifiée par la propriété lastIndex, et si elle trouve une correspondance , il définit la propriété lastIndex sur le numéro de position du caractère suivant directement la correspondance trouvée. Par conséquent, en utilisant la méthode test(), vous pouvez également former une boucle de parcours de chaîne, comme en utilisant la méthode exec().