15/11/2024

PowerShell

PowerShell et les RegEx (Expressions régulières)

I. Présentation

Comme de nombreux langages, PowerShell est compatible avec les expressions régulières (RegEx) et cela va permettre de vérifier si une chaîne est conforme à un format que l'on définit grâce à une expression régulière. Très puissantes, les expressions régulières ne sont pas forcément faciles à prendre en main... Elles sont bien plus connues par les administrateurs système sous Linux, que sous Windows. Dans cet article, nous allons découvrir les RegEx PowerShell ensemble avec différents exemples, car je pense que c'est le meilleur moyen de les prendre en main.

Grâce à une expression régulière, voici quelques exemples de ce que l'on peut vérifier :

  • La chaîne contient au moins un chiffre
  • La chaîne contient au mois un espace
  • La chaîne se termine par un caractère spécifique
  • La chaîne commence par un caractère spécifique
  • La chaîne est d'une longueur spécifique
  • La chaîne est d'une longueur comprise en X et Y caractères
  • Etc.

Toutes ces conditions sont cumulables : c'est là que ça devient puissant et précis ! Par exemple, une expression régulière va permettre de valider les données saisies, pour contrôler par exemple qu'il s'agisse bien d'une adresse e-mail, d'une date ou d'une adresse IP.

Les expressions régulières sont alors des filtres de recherche très puissants au sein d'un ensemble de données ou du contenu d'un fichier.

Ce tutoriel est disponible au format vidéo :

II. RegEx : les opérateurs de comparaison

Pour exploiter les expressions régulières, PowerShell propose quatre opérateurs de comparaison différents :

  • -match : comparaison d'égalité entre une chaîne ou une expression et une expression régulière (correspond à...) / sensible à la casse
  • -notmatch : comparaison d'inégalité entre une chaîne ou une expression et une expression régulière (ne correspond pas à...) / sensible à la casse

Ainsi que deux autres opérateurs qui sont sensibles à la casse :

  • -cmatch : correspond à...
  • -cnotmatch : ne correspond pas à...

Ces opérateurs vont s'utiliser de la façon suivante :

"chaine-de-caractères" -match "pattern"

Lorsque l'on définit une expression régulière, on nomme l'expression "un modèle" et bien souvent nous parlons de pattern. Il est à noter que les expressions régulières peuvent être utilisées avec des méthodes également, comme Replace() et Split().

III. Symboles de base - RegEx PowerShell

Le tableau ci-dessous regroupe les symboles de base que vous pouvez utiliser avec les expressions régulières en PowerShell. Nous allons les utiliser dans les exemples qui vont suivre.

Caractères Usage
^ Début d’une ligne
$ Fin d’une ligne
\A Début d’une chaîne de caractères
\Z Fin d’une chaîne de caractères
\d Contient au moins un chiffre
\D Ne contient aucun chiffre
\w Englobe les lettres et les chiffres
(a|b) Contient « a » ou « b »
[] Plage de caractères
[a-f] Contient une lettre en minuscule comprise entre « a » et « f »
[^a-f] Contient une lettre en minuscule qui n’est pas comprise entre « a » et « f »
[A-F] Contient une lettre en majuscule comprise entre « A » et « F »
{} Longueur de la chaîne
{1,4} Longueur entre 1 et 4 caractères
{4,} Longueur de moins de 4 caractères
* De 0 à X caractères, peu importe le caractère
+ De 1 à X caractères, peu importe le caractère

En complément, je vous recommande de consulter ce document : Regex

IV. Le caractère d'échappement

Lorsque l'on écrit une expression régulière, on s'appuie sur des caractères spéciaux. Ceci peut poser problème si l'on souhaite qu'un caractère soit pris en compte littéralement et qu'il ne soit pas interprété comme étant une expression régulière. Nous devons alors utiliser un caractère d'échappement.

En PowerShell, le caractère d'échappement est l'anti-slash, c'est-à-dire "\". Si l'on veut que le signe "$" soit pris en compte littéralement et non comme une RegEx, on devra indiquer "\$".

Passons maintenant aux exemples, tout cela sera plus parlant et permettra de voir tout ça dans la pratique...

V. Exemples de RegEx en PowerShell

Je vous propose plusieurs exemples, plus ou moins simples, afin de vous aider à bien comprendre les expressions régulières et vous aider pour construire votre propre RegEx !

A. La chaîne commence par le caractère "w"

$Expression = "www.it-connect.fr"
$Expression -match "^w"

Cette RegEx retournera "True" puisque le premier caractère de la chaîne est bien "w". Puisque -match n'est pas sensible à la casse et que ce pattern ne l'est pas non plus, ceci fonctionnera aussi avec un "W" majuscule :

$Expression -match "^W"

B. La chaîne se termine par le caractère "r"

$Expression = "www.it-connect.fr"
$Expression -match "r$"

Ceci retournera True.

C. La chaîne contient-elle un chiffre ?

$Expression = "www.it-connect.fr"
$Expression -match "\d"

Le résultat sera False puisque la chaîne $Expression ne contient pas de chiffre. Par contre si l'on utilise \D, elle retournera vrai puisqu'elle n'en a pas.

$Expression -match "\D"

D. La chaîne commence-t-elle par une majuscule ?

Puisqu'ici on s'intéresse à la casse, on va utiliser plutôt -cmatch que -match.

$Expression = "IT-Connect"
$Expression -cmatch "^[A-Z]{1}"

On va s'intéresser au début de la chaîne grâce à "^" puis nous allons définir la plage de caractères "[A-Z]" pour prendre tout l'alphabet, et on cherchera à vérifier s'il y a bien un caractère qui correspond à la place {1}. Si l'on veut s'assurer que les deux premiers caractères soient en majuscules, on utilisera :

$Expression -cmatch "^[A-Z]{2}"

Nous pourrions aller plus loin et nous assurer qu'il y a seulement la première lettre comme majuscule, pour l'écriture d'un prénom par exemple. Ce qui donne :

$Expression = "Florian"
$Expression -cmatch "^[A-Z]{1}[a-z]+$"

E. Accepter plusieurs variantes d'une chaîne

Par exemple, si l'on cherche à vérifier que la chaîne est égale à "powershell", "powersholl" ou "powershull", on utilisera cette RegEx :

$Expression = "powershell"
$Expression -match "powersh[eou]ll"

La valeur "powershell" retournera True alors que "powershall" retournera False.

F. Vérifier une adresse e-mail avec une RegEx

Premier cas : une adresse e-mail avec le format [email protected] :

$Email = "[email protected]"
$Email -cmatch "^[a-z][email protected]$"

Deuxième cas : une adresse e-mail avec le format [email protected]

$Email = "[email protected]"
$Email -cmatch "^[a-z]+\.[a-z][email protected]$"

Si l'on veut accepter l'un des deux formats précédents, cela donne :

$Email -cmatch "^(([a-z]+)|([a-z]+\.[a-z]+))@it-connect.fr$"

Jusqu'ici, nous avons vérifié une adresse e-mail avec un domaine "fixe". Si l'on veut vérifier le format d'une adresse e-mail générique, la RegEx sera à peine plus complexe puisqu'il faut deux valeurs séparées par un "." après le "@" :

$Email -cmatch "^[a-z]+\.[a-z]+@[a-z]+\.[a-z]+$"

Le pattern ci-dessus fonctionne bien, mais il n'autorise pas les chiffres dans l'adresse e-mail. Si l'on veut un domaine avec seulement des lettres et autoriser les chiffres et les lettres pour la partie nom d'utilisateur, on s'appuiera sur [\w] plutôt que [a-z].

Pour une adresse e-mail sous la forme "prenom.nom@it-connect.fr" :

$Email -cmatch "^[\w]+\.[\w]+@[a-z]+-[a-z]+\.[a-z]+$"

Pour cet exemple, les adresses e-mails suivantes renverraient "True" :

Si le domaine de votre e-mail est constitué d'un seul bloc sans "-", utilisez plutôt :

$Email -cmatch "^[\w]+\.[\w]+@[a-z]+\.[a-z]+$"

G. Vérifier une adresse IP avec une RegEx

Sur le principe, une adresse IP est représentée avec 4 blocs de 1 à 3 chiffres, séparés par un point. Pour créer un pattern qui va vérifier que le bloc fait bien entre 1 et 3 chiffres, on va utiliser ceci :

\d{1,3}

Puis, nous allons ajouter le "." pour séparer les blocs :

\.

Il ne reste plus qu'à répéter cette opération. Le pattern final pour vérifier une adresse IP sera :

$AdresseIP = "10.11.12.13"
$AdresseIP -match "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"

Ce n'est pas un pattern parfait puisqu'il ne vérifie pas la valeur maximale de chaque bloc. Par exemple, l'adresse IP "510.511.512.513" serait considérée comme valide. En fait, ce pattern vérifie la structure de l'adresse IP et le type de valeurs, sans gérer la notion de valeurs maximales.

Si l'on veut utiliser un pattern qui est plus précis, notamment pour éviter les valeurs impossibles, notamment supérieures à 255, cela donne :

$AdresseIP -match "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$"

Vous remarquerez la présence de "|" pour permettre plusieurs valeurs. Par exemple, étudions le pattern pour le premier bloc :

^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])

Ainsi, l'adresse IP devra commencer soit par une valeur comprise entre 1 et 9, ou entre 10 et 99, ou entre 100 et 199, ou entre 200 et 249, ou enfin entre 250 et 255. Afin de définir une plage de valeurs entre 1 et 255, c'est de cette façon qu'il faut s'y prendre.

H. Vérifier la date avec une RegEx

Si l'on veut s'assurer que la date est sous la forme "XX/YY/ZZZZ" avec seulement des chiffres, on devra utiliser \d une fois de plus et penser à préciser "/" avec "\" pour faire l'échappement. Ce qui donne :

$Date = "19/10/1991"
$Date -match "(\d{1,2}\/\d{1,2}\/\d{4})$"

Rien n'empêche de définir une date avec le jour 32 ou 50, ou alors le mois "15". Pour, une nouvelle fois, affiner notre pattern afin d'être plus précis, notamment pour que le jour soit compris entre 01 et 31, et le mois entre 01 et 12, cela va donne le pattern suivant :

$Date -match "^(0[1-9]|[1-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\/(\d{4})$"

Je vous laisse tester pour vérifier que ça fonctionne ?

I. Vérifier une adresse HTTP/HTTPS avec une RegEx

Si l'on veut simplement vérifier qu'une chaine commence par HTTP ou HTTPS, c'est très simple. Commençons par définir une adresse :

$Link = "https://www.domaine1.fr"

Grâce au pattern ci-dessous, nous allons vérifier le début de l'adresse :

$Link -match "^(https://|http://)"

Si l'on veut aller plus loin en vérifiant que le lien est composé de quatre blocs, en autorisant seulement les chiffres dans le bloc domaine grâce à \W :

<protocole><sous-domaine>.<domaine>.<TLD>

Ce qui donne :

$Link -match "^(https://|http://)([a-z]+\.)(\w+\.)([a-z]+)$"

Notre adresse "https://www.domaine1.fr" fonctionnera, ce qui ne sera pas le cas de :

  • https://www1.domaine.fr
  • https://www.domaine1.f2r
  • hhhhhttps://www.domaine.fr

J. Vérifier un nom de fichier avec une RegEx

Pour vérifier un nom de fichier ou plutôt s'assurer qu'il correspond à un type d'extension spécifique, là encore les expressions régulières vont s'avérer très pratiques. On peut reprendre le même principe que pour les adresses Web, sauf qu'ici on va plutôt s'intéresser à la fin de la chaîne.

Voici un exemple avec les extensions "psd1" et "ps1" :

$File = "MonFichier.ps1"
$File -match "(.psd1|.ps1)$"

Cet article est désormais terminé, j'espère qu'il vous motivera à tenter votre chance avec les expressions régulières et surtout qu'il va vous aider à construire vos premières RegEx ! Si vous avez une question, je vous invite à laisser un commentaire sur l'article ?

author avatar
Florian BURNEL Co-founder of IT-Connect
Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

2 commentaires sur “PowerShell et les RegEx (Expressions régulières)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.