
Les expressions régulières
Les expressions régulières sont un outil transverse aux langages de programmation. Et que tu sois un développeur php ou javascript ou autre, quand un collègue te demande un coup de main pour écrire sa regexp (parce que regular expression c’est trop long), tu hésites et c’est normal.
Pourquoi les regexp ?
C’est une sorte de fonction de recherche dans une chaîne de caractères. Mais pas que. En plus, elles permettent aussi faire de la validation ou de l’extraction de données.
Donc si tu veux :
- valider le format d’une chaîne (ex : une adresse web),
- extraire une portion de chaîne (ex : le type de rue dans une adresse)
Les regexp sont là pour toi.
Délimiteurs
Une regexp est toujours entourée de délimiteur. Tu peux mettre ce que tu veux mais hésite pas trop longtemps. Perso entre le /
et le #
mon coeur balance.
/regexp/
Prenons la chaîne suivante : Hello world!
.
Pour tester que world
est présent, ça donne simplement :
/world/
Début et fin de chaîne
Ok mais moi je veux tester que ca commence par “world”.
Tu es bien exigeant jeune padawan, mais pour répondre à ta question, c’est pour ça qu’il existe des marqueurs de début et fin de chaîne : respectivement ^
et $
.
/^world/
Les caractères
Bon un mot exact dans une chaîne c’est bien mignon mais dans la vrai vie (de dev) ta recherche est plus abstraite que ça. Donc voici comment tu peux utiliser les caractères dans ta regexp :
- [a-z] : Caractères minuscules de a à z.
- [0-9] : Chiffres de 0 à 9.
- [a-z0-9] : Lettres de « a » à « z » ou chiffres de 0 à 9.
- #[^0-9]# : Chaîne ne contenant PAS de chiffres.
T’as vu le dernier de la liste ?
Pour faire une négation c’est avec un ^
, le même caractère que pour un début de chaîne.
Ouai faut le savoir…
Les quantifieurs
Bah oui, ça va avec les caractères que l’on a vu au-dessus.
- #a?# : « a » peut apparaître 0 ou 1 fois.
- #a+# : « a » doit apparaître au moins 1 fois.
- #a*# : « a » peut apparaître 0, 1 ou plusieurs fois.
- #a{3}# : « a » doit apparaître 3 fois exactement (« aaa »).
- #a{3,5}# : « a » doit apparaître de 3 à 5 fois (« aaa », « aaaa », « aaaaa »).
Donc si on applique la regexp suivante sur notre
Hello world!
ca marche ?
/[a-z]+/
Et non ! La majuscule, l’espace et le point d’exclamation, tu ne gères pas ces éléments dans ta regexp.
Ca sert à rien mais si tu veux valider ton Hello world!
, ça donnerait plutôt :
/^[a-zA-Z !]+$/
Au fait, tu ne m’as pas demandé pourquoi des délimiteurs ? Du coup j’y répond quand même : c’est parce que y’a des options possibles et qu’ils se mettent en fin de l’expression.
/regexp/options
Tu veux la liste de ces options ? Ok, voici :
- g : Global
- m : Multiline
- i : Case insensitive
- x : Ignore whitespace
- s : Single line
- u : Unicode
- X : eXtended
- U : Ungreedy
- A : Anchor
- J : Duplicate group names
Tu as reperé le i
pour gérer la casse ? Donc ça veut dire qu’on peut améliorer notre regexp :
/^[a-z !]+$/i
Quelques exemples
Allez en vrac quelques regexp pour te montrer ce que ça peut vite devenir compliquer.
Mot de passe complexe
/^ # Début de chaîne
(?=(.*[0-9])) # Au moins 1 chiffre
(?=.*[a-z]) # Au moins 1 minuscule
(?=(.*[A-Z])) # Au moins 1 majuscule
(?=.*[\!@#$%^&*()\\\\[\]{}\-_+=~`|:;"\'<>,.\/?]) # Au moins 1 caractère spéciale
(?=(.*)).{8,} # Au moins 8 caractères
$ # Fin de chaîne/mx
Numéro de sécurité sociale
/^ # début de chaîne
(?<sexe>[12]) # 1 ou 2 pour le sexe
(?<naissance>[0-9]{2}(?:0[1-9]|1[0-2])) # année et mois de naissance (aamm)
(?<departement>2[AB]|[0-9]{2}) # le département
(?<postal_code>[0-9]{3}) # suite du code postal sur trois chiffres
(?<numserie>[0-9]{3}) # numéro de série sur trois chiffres
(?<controle>[0-9]{2})? # numéro de contrôle (facultatif)
$ # fin de chaîne/x
Bah c’est quoi les
?<...>
que tu nous mets là ?
C’est pour nommer tes groupes, ça rend les éléments que tu captures plus lisible je trouve.
Car oui je n’ai fait que survoler le sujet, il y a encore des choses à dire (les shortcodes, l’échappement, …), mais je te laisse faire tes propres recherches ;)