Les expressions régulières (regex ou regexp) sont extrêmement utiles pour extraire des informations d’un texte en recherchant une ou plusieurs correspondances à l’aide d’un modèle de recherche spécifique (c’est-à-dire une séquence spécifique de caractères ASCII ou Unicode). Voici un rapide tuto regex pour avoir une vision d’ensemble de ce domaine.
Les domaines d’application vont de la validation à l’analyse/remplacement de chaînes de caractères, en passant par la transposition de données vers d’autres formats mais aussi le web scraping (lire l’article).
L’une des fonctionnalités les plus intéressantes c’est qu’une fois que vous avez appris la syntaxe, vous pouvez l’utiliser dans (presque) tous les langages de programmation (JavaScript, Java, VB, C #, C / C ++, Python, Perl, Ruby). , Delphi, R, Tcl et bien d’autres) avec quelques légères distinctions pour les fonctionnalités les plus avancées et les versions de syntaxe prises en charge par les moteurs. Si vous êtes débutant, je vous recommande ce tuto sur les regex sur google sheet.
Commençons par regarder quelques exemples et explications.
Tuto regex : Les bases
Les ancres ^ et $
- ^Alors correspond à toute chaîne de caractères qui commence par « Alors » -> Je teste !
- fin$ correspond à toute chaîne de caractères qui se termine par « fin«
- ^la fin$ correspond exactement à la chaîne de caractères « la fin«
- on correspond à toute chaîne de caractères qui a « on » à l’intérieur
Exemple code Python:
import re regex = r"^Alors" test_str = "Alors on danse !!!" matches = re.finditer(regex, test_str) for matchNum, match in enumerate(matches): matchNum = matchNum + 1 print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group())) for groupNum in range(0, len(match.groups())): groupNum = groupNum + 1 print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))
Les quantificateurs *, +, ? et {}
- abc* correspond à une chaîne de caractères qui possède « ab » suivi de zéro ou plusieurs « c » -> Je teste !
- abc+ correspond à une chaîne de caractères qui possède « ab » suivi d’un ou plusieurs « c«
- abc? correspond à une chaîne de caractères qui possède « ab » suivi de zéro ou un « c«
- abc{2} correspond à une chaîne de caractères qui possède « ab » suivi de 2 « c«
- abc{2,} correspond à une chaîne de caractères qui possède « ab » suivi de 2 (ou plus) « c«
- abc{2,5} correspond à une chaîne de caractères qui possède « ab » suivi de 2 à 5 « c«
- a(bc)* correspond à une chaîne de caractères qui possède un « a » suivi de zéro ou plusieurs séquences « bc«
- a(bc){2,5} correspond à une chaîne de caractères qui possède un « a » suivi de 2 à 5 copies de la séquence « bc«
L’opérateur OU : | ou []
- a(b|c) correspond à une chaîne de caractères qui possède un « a » suivi de « b » ou « c » -> Je teste !
- a[bc] exactement même résultat, toutes les lettres entre crochet sont une alternative, retourne donc les chaînes de caractères correspondant à « ab » ou « ac«
Les classes de caractère: \d, \w, \s et .
- \d correspond à un seul caractère qui est un chiffre -> Je teste !
- \w correspond à un caractère de mot (comprend lettres, chiffres et underscore) -> Je teste !
- \s correspond à un caractère d’espace (comprend les tabulations et les sauts de ligne)
- . correspond à n’importe quel caractère -> Je teste !
Utilisez l’opérateur . avec précaution car souvent la classe de caractères ou la classe de caractères inversée (traitée ci-dessous) sont plus rapides et plus précises.
\d, \w et \s présentent également leurs négations avec \D, \W et \S respectivement.
Par exemple, \D effectuera la correspondance inverse par rapport à celle obtenue avec \d.
- \D correspond à un seul caractère non numérique -> Je teste !
Pour être pris littéralement, vous devez annuler l’effet des caractères ^. [$ () | * +? {\ avec une barre oblique inversée \ car ces éléments ont une signification particulière (contrairement à d, w et s).
- \$\d correspond à une chaîne qui a un $ avant un chiffre -> Je teste !
Notez que vous pouvez également faire correspondre des caractères non affichables tels que les tabulations \t, les nouvelles lignes \n et les retours chariot \r.
Les indicateurs
Afin d’apprendre à construire un regex efficacement, on ne peut oublier un concept fondamental: les indicateurs.
Une expression rationnelle vient généralement avec cette forme /abc/, où le motif de recherche est délimité par deux barres obliques /. A la fin, nous pouvons spécifier un indicateur avec ces valeurs (nous pouvons également les combiner):
- g (global) permet de ne pas revenir après la première correspondance trouvée, cela relance les recherches suivantes à partir de la fin du match précédent
- m (multi line): lorsqu’il est activé ^ et $ correspondront au début et à la fin d’une ligne, au lieu de la chaîne de caractères entière
- i (insensitive) rend l’expression entière insensible à la case (par exemple, /aBc/i correspondrait à AbC)
Tuto regex : Niveau intermédiaire
Regroupement et capture: ()
- a(bc) crée un groupe de capture avec la valeur bc -> Je teste !
- a(?:bc)* en utilisant ?: nous désactivons le groupe de capture -> Je teste !
- a(?<foo>bc) en utilisant ?<foo> nous donnons un nom au groupe -> Je teste !
Cet opérateur est très utile lorsque nous devons extraire des informations de chaînes de caractères ou de données en utilisant votre langage de programmation préféré. Toutes les occurrences multiples capturées par plusieurs groupes seront exposées sous la forme d’un tableau classique: nous accéderons à leurs valeurs en spécifiant à l’aide d’un index sur le résultat de la correspondance.
Si nous choisissons de nommer les groupes (avec (?<Foo>…)), nous pourrons récupérer les valeurs du groupe en utilisant le résultat de la correspondance, comme un dictionnaire où les clés seront le nom de chaque groupe.
Expressions entre crochets : []
- [abc] correspond à une chaîne de caractères qui a un a ou un b ou un c (est identique à a|b|c) -> Je teste !
- [a-c] exactement la même chose, littéralement tout caractère de a à c.
- [a-fA-F0-9] une chaîne de caractères représentant un seul caractère d’un chiffre hexadécimal, sans distinction de case -> Je teste !
- [0-9]% une chaîne de caractères qui a un chiffre de 0 à 9 avant le signe %
- [^a-zA-Z] une chaîne de caractères qui ne contient aucune lettre de a à z ou de A à Z. Dans ce cas, le ^ est utilisé comme négation de l’expression -> Je teste !
Rappelez-vous que dans les expressions entre crochets, tous les caractères spéciaux (y compris la barre oblique inverse \) perdent leurs pouvoirs spéciaux: nous n’appliquerons donc pas la règle d’annulation.
Correspondance généreuse vs. plus sélect
Les quantificateurs (* + {}) sont des opérateurs généreux. Ils étendent la correspondance aussi loin que possible à travers le texte fourni.
Par exemple, <.+> correspond à <div>simple div</div> dans Ceci est un test d’un <div>simple div</div>. Afin d’attraper uniquement la balise div, nous pouvons utiliser un ? pour le rendre plus sélect:
<.+?> correspond à tout caractère une ou plusieurs fois inclus entre < et > -> Je teste !
Notez qu’une meilleure solution devrait éviter l’utilisation de . en faveur d’un regex plus strict:
<[^<>]+> correspond à n’importe quel caractère sauf < ou > une ou plusieurs fois inclus entre < et > -> Je teste !
Tuto regex : Niveau avancé
Limites : \b et \B
- \babc\b effectue une recherche « mots entiers uniquement » -> Je teste !
\b représente une ancre lambda (il est similaire à $ et ^) des positions correspondantes où un côté est un caractère de mot (comme \w) et l’autre côté n’est pas un caractère de mot (par exemple, il peut s’agir du début de la chaîne de caractères ou un espace).
Il vient avec sa négation \B. Cela correspond à toutes les positions où \b ne correspond pas. Cela peut être le cas si nous voulons trouver un modèle de recherche entièrement entouré de caractères.
- \Babc\B ne correspond que si le motif est entièrement entouré de caractères -> Je teste !
Références arrières : \1
- ([abc])\1 en utilisant \1, il correspond au même texte que le premier groupe de capture -> Je teste !
- ([abc])([de])\2\1 nous pouvons utiliser \2 (\3, \4, etc.) pour identifier le même texte correspondant au deuxième (troisième, quatrième, etc.) groupe de capture. -> Je teste !
- (?<foo>[abc])\k<foo> nous donnons le nom foo au groupe et nous le référençons plus tard (\k<foo>). Le résultat est le même que celui du premier regex -> Je teste !
Observation avant et après : (?=) Et (?<=)
- d(?=r) ne correspond à d que si l’est suivi de r, mais r ne fera pas partie du résultat -> Je teste !
- (?<=r)d ne correspond à d que s’il est précédé d’un r, mais r ne fera pas partie du résultat -> Je teste !
Vous pouvez également utiliser l’opérateur de négation!
- d(?!r) ne correspond à d que s’il n’est pas suivi de r, mais r ne fera pas partie du résultat -> Je teste !
- (?<!r)d ne correspond à d que s’il n’est pas précédé d’un r, mais r ne fera pas partie du résultat -> Je teste !
Pour conclure
Comme vous l’avez vu dans ce tuto regex, les champs d’application de regex peuvent être multiples et je suis sûr que vous avez reconnu au moins une façon de les utiliser, voici une liste rapide:
- Validation des données (par exemple, vérifier si une chaîne de caractères temporelle comme une date est bien formée)
- Scraping de données (par exemple sur le Web, trouvez toutes les pages contenant un certain ensemble de mots dans un ordre spécifique)
- Correspondance de données (transformer des données «brutes» dans un autre format)
- Analyse de chaîne de caractères (par exemple, capture de tous les paramètres GET de l’URL, capture du texte entre parenthèses)
- Remplacement de chaîne de caractères (même pendant une session de code utilisant un IDE commun, par exemple, transformer une classe Java ou C # dans l’objet JSON correspondant – remplacer « ; » par « , » le mettre en minuscule, éviter la déclaration de type, etc.)
- Mise en évidence de la syntaxe, changement de nom de fichier, détection de paquets et de nombreuses autres applications impliquant des chaînes de caractères (où les données n’ont pas besoin d’être textuelles)
Amusez-vous bien et n’oubliez pas de recommander l’article si vous l’avez aimé <3