Regex : Moins effrayant qu'il n'y paraît
Les expressions régulières ont la réputation d'être illisibles. Elles n'ont pas à l'être.
Tu dois trouver toutes les adresses email dans un document. Ou valider des numéros de téléphone. Ou extraire des dates d'un texte désordonné.
Quelqu'un dit "utilise du regex." Tu googles la syntaxe, trouves quelque chose comme ^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$, et fermes immédiatement l'onglet.
Les expressions régulières ont l'air intimidantes parce que les gens les écrivent pour être malins au lieu d'être clairs. Réglons ça.
Commence par la correspondance littérale
Regex trouve des motifs. Le motif le plus simple est du texte littéral.
cat correspond à "cat" dans "The cat sat." Rien de fantaisiste.
http correspond à "http" dans n'importe quelle URL. Toujours simple.
Ajoute des jokers graduellement
. correspond à n'importe quel caractère unique. c.t correspond à "cat", "cot", "cut".
* signifie "zéro ou plus du précédent". ca*t correspond à "ct", "cat", "caat", "caaaaaat".
+ signifie "un ou plus". ca+t correspond à "cat" et "caat" mais pas "ct".
? signifie "zéro ou un". colou?r correspond à la fois à "color" et "colour".
Les classes de caractères sont tes amies
[aeiou] correspond à n'importe quelle voyelle. [0-9] correspond à n'importe quel chiffre. [A-Za-z] correspond à n'importe quelle lettre.
\d est l'abréviation de [0-9]. \w correspond aux caractères de mot (lettres, chiffres, underscore). \s correspond aux espaces blancs.
Ces briques gèrent la plupart des motifs du monde réel.
Les ancres contrôlent la position
^ signifie "début de ligne". $ signifie "fin de ligne".
^Hello correspond à "Hello world" mais pas "Say Hello".
world$ correspond à "Hello world" mais pas "world peace".
Les groupes capturent des parties
Les parenthèses regroupent des choses. Elles capturent aussi pour usage ultérieur.
(\d{3})-(\d{4}) correspond à "555-1234" et capture "555" et "1234" séparément.
C'est comme ça que tu extrais des données spécifiques d'une correspondance de motif.
Exemples réels, expliqués
Email (simplifié) :
[\w.-]+@[\w.-]+\.\w+
Traduction : caractères de mot/points/tirets, puis @, puis plus de la même chose, puis un point, puis caractères de mot.
Numéro de téléphone :
\d{3}[-.\s]?\d{3}[-.\s]?\d{4}
Traduction : 3 chiffres, séparateur optionnel, 3 chiffres, séparateur optionnel, 4 chiffres. Correspond à "555-123-4567", "555.123.4567", "5551234567".
Date (MM/DD/YYYY) :
\d{2}/\d{2}/\d{4}
Traduction : 2 chiffres, slash, 2 chiffres, slash, 4 chiffres.
Erreurs courantes
Oublier d'échapper les caractères spéciaux. . signifie "n'importe quel caractère" en regex. Pour correspondre à un point littéral, utilise \..
Être trop gourmand. .* correspond à autant que possible. Pour les balises HTML, <.*> sur <b>bold</b> correspond au tout, pas juste <b>. Utilise <.*?> pour correspondance non gourmande.
Sur-compliquer. Si tu dois valider des emails pour de vrai, utilise une bibliothèque. Le regex email "correct" fait des centaines de caractères.
Quand ne pas utiliser Regex
Parser du HTML ou JSON. Utilise un parser approprié.
Logique de validation complexe. Le code est souvent plus clair qu'un seul motif massif.
Quand les méthodes de chaîne fonctionnent. "hello".startsWith("he") est plus clair que /^he/.
Regex est un outil. Comme tout outil, il est bon pour des tâches spécifiques et maladroit pour d'autres. Commence simple, teste au fur et à mesure, et n'essaie pas d'être malin. Du regex lisible est mieux que du regex impressionnant.