Sylver SCHORGEN Blog's

Articles, astuces et news sur les technologies Microsoft et plus particulièrement tournant autour de Powershell

Pour mon premier article sur ce blog je vais essayer de vous exposer les bases des expressions régulières (regex) afin que vous puissiez vous-même les écrire dans vos scripts Smile

Que cela soit en Powershell ou d'en d'autres langages, beaucoup (trop) de personnes (dont j'ai fait partie pendant quelques temps) font des "copier/coller" de bouts de codes trouvés sur internet et les modifient un peu pour les adapter à leurs besoins sans réellement comprendre les regex en elles mêmes.

Le but de cet article est donc de vous expliquez les bases afin que vous puissiez comprendre les regex et que vous puissiez les réaliser par vous-même. On essaye souvent de faire sans mais les regex s'avèrent être d'une grande utilité dans beaucoup de scripts pour effectuer, notamment, des actions de validation (adresse mail, URL, chemin UNC, nom, ...).

Si je vous montre cette chaîne de caractères "sschorgen@microsofttouch.fr", vous allez tout de suite l'identifier comme étant une adresse e-mail. Votre ordinateur, quant à lui, va être incapable, de lui même, de faire la différence entre "sschorgen@microsofttouch.fr" et "http://www.microsofttouch.fr". Pour lui, les 2 correspondent à des chaînes de caractères. Il va donc falloir lui indiquer comment reconnaître que la 1ère est une adresse e-mail et la 2ème une URL. Pour ce faire, nous allons utiliser des regex.

L'opérateur de comparaison match

"-match" est l'opérateur que l'on va utiliser lorsque l'on voudra évaluer une chaîne de caractères à une regex.

Exemple:  "ma_chaine_de_caracteres" -match "ma_regex"

Cet opérateur retournera True si la chaîne de caractère source match la regex et retournera False dans le cas contraire.

Par défaut, l'opérateur -match n'est pas sensible à la casse. Ainsi, dans le premier exemple ci-dessus "Touch" ou "touch" aurait retourné True. Si vous voulez que la casse soit prise en compte, il suffit d'utiliser l'opérateur "-cmatch" ('c' comme 'case sensitive'). 

Répétition et généricité

Dans les exemples ci-dessus, on cherche tout simplement à matcher une partie du mot. Les regex sont plutôt utilisées pour vérifier la structure de la chaîne de caractères. Pour ce faire, nous pouvons utiliser des caractères dit "génériques". Il en existe 2 :

  • '?' : correspond à 0 ou 1 fois n'importe quel caractère
  • '.' : correspond à 1 fois n'importe quel caractère

Par exemple on pourrait vérifier que notre chaîne commence par la lettre 'M', puis 0 ou 1 lettre (n'importe laquelle), puis "crosoftTouch"

Il est également souvent nécessaire de vérifier si un ou plusieurs caractères se répètent. Il existe pour cela 2 caractères dit de "répétitions" :

  • '*' : Permet de vérifier si le ou les caractères spécifiés avant le * se répètent 0 ou plusieurs fois
  • '+' : Permet de vérifier si le ou les caractères spécifiés avant le + se répètent 1 ou plusieurs fois

Ainsi, si on voulait vérifier que dans "MicroMicrosoftTouch", la chaîne de caractère "Micro" se répètent une fois ou plus sans être sensible à la casse, on ferait ceci :

Groupe de caractères

Imaginons que l'on sache que notre mot commence par "Microsoftto", se termine par "ch" et que l'on veuille vérifier si la lettre entre "Microsoftto" et "ch" est soit un 'o', soit ou un 'i', soit un 'u'. Nous n'allons pas utiliser le '.' car ce dernier correspond à n'importe quel caractère. Nous allons alors utiliser ce que l'on appelle un groupe de caractères comme ci-dessous :

Le groupe de caractères est donc un ensemble de lettres ou de chiffres à l'intérieur de [ ]. Il est, bien entendu possible de combiner les groupes de caractères avec les caractères de répétitions et les caractères génériques. 

Si on veut vérifier la présence d'un caractère allant, par exemple, de A à H, dans une chaîne, on peut le faire comme ceci [A-H] au lieu d'écrire tous les caractères de la sorte [ABCDEFGH]. Cela fonctionne exactement de la même façon pour les chiffres et il est même possible de combiner chiffres et lettres [A-H0-7] si on s'attend à ce qu'il y ait soit une lettre soit un chiffre à cet emplacement.

Au niveau des 2 premiers exemples ci dessus, nous testons si, après le 1er caractère 'o', il y a un caractère étant entre 'o' et 'u' dans l'alphabet. Au niveau du dernier exemple, nous testons si, après le caractère 'M', il y a soit un "i", soit un '1'.

Il existe également plusieurs caractères spéciaux qui correspondent à des groupes de caractères plus larges dont :

  • '\s' : correspond à 1 ou plusieurs espace (peut importe que cela soit équivalent à un espace ou une tabulation
  • '\S' : correspond à 0 espaces
  • '\w' : correspond à 1 ou plusieurs chiffres ou lettres
  • '\W' : correspond à 0 chiffre ou lettre
  • '\d' : correspond à 1 ou plusieurs chiffres
  • '\D' : correspond à 0 chiffre

Le début et la fin d'une chaîne

Par exemple, Dans le cadre d'un nom propre, d'un nom de famille ou d'un prénom, on peut être amener à vouloir vérifier si le contenu de la variable contenant cette chaîne de caractères commence bien par une majuscule et termine bien par un minuscule. Le caractère '^' nous permet d'indiquer le début d'une chaîne de caractères alors que le '$' nous sera utile afin d'en spécifier la fin.  Ainsi, si je veux vérifier que "MicrosoftTouch" commence par une majuscule et termine par une minuscule, je ferai ceci :

Attention : Le caractère '^' situé en plein milieu d'une regex correspond à la négation - cela signifie donc "ne contient pas"

Echapper des caractères

Avec tous les caractères spéciaux que nous avons vu jusqu'ici, vous vous demandez peut-être comment faire s'il on veut vérifier que notre chaîne de caractères dispose d'un '*' ou d'un '+' ou encore d'un '?'. Et bien il suffit d'échapper ce caractère avec '\'.

Exemple final

Afin de conclure cet article voici un petit exemple permettant de vérifier que le nom et le prénom commence bien par une majuscule, ainsi que de vérifier que l'adresse mail de l'utilisateur est valide et se termine bien par @microsofttouch.fr. Si le nom ou le prénom n'est pas valide on le corrige. Si le mail n'est pas valide on affiche un message au niveau de la console.

function demoRegex() {
$prenom = 'Sylver'
$nom = 'schorgen'
$mail = 'sschorgen@microsofttouch.fr'
$matchNoms = '^[A-Z].[A-Za-z]+$'
$matchMail = '^[a-z]+\.*\-*[a-z]*@microsofttouch.fr$'
if(!($prenom -cmatch '^[A-Z].[A-Za-z]+$')) {
     $prenom = (Get-Culture).TextInfo.ToTitleCase($prenom)
     Write-Host "Le prénom a été corrigé"
}
if(!($nom -cmatch '^[A-Z].[A-Za-z]+$')) {
     $nom = (Get-Culture).TextInfo.ToTitleCase($nom)
     Write-Host "Le nom a été corrigé"
}
if(!($mail -match '^[a-z]+\.*\-*[a-z]*@microsofttouch.fr$')) {
     Write-Host "L'adresse mail n'est pas valide"
     Write-Host "L'adresse mail doit-être du type dutexte@microsofttouch.fr"
}

La fonction est également fourni en pièce jointe à cet article.

Facebook Like