Ajouter aux favoris  Imprimer  www.labo-dotnet.com
 
 

Les expressions régulières en c#

Par  Marc Falesse
Publié le 25/05/2003

Les expressions régulières


1 - Introduction

De quoi s’agit-il ? Les expressions régulièrement permettent de vérifier si une chaîne de caractères respecte bien certaines règles ; par exemple un site web pourra avoir recours à une expression régulière pour vérifier la syntaxe d’une adresse email; remplacer un bout un texte par un autre ; ou même identifier des certaines zones dans une chaîne de caractères, on pourra par exemple extraire d’une URL : le protocole, le serveur, la donnée. 

Où ? Les expressions régulières, souvent abrégé en regexp ou regex, sont très utilisées dans le monde UNIX, notamment avec la commande grep qui permet de filtrer des données. Elles sont également très utilisées par le langage perl, qui les a empruntées au sed. 

What’s more ? Les expressions régulières ont été étudiées par les mathématiciens qu’ils préfèrent appeler « expressions rationnelles ». Le théorème de Kleene dit : « un langage est reconnaissable par un automate fini si et seulement si il est rationnel ». En fait, en mathématique, il s’agit de vérifier si une chaîne appartient à un langage, c’est-à-dire qu’elle respecte sa grammaire. Un automate fini est représenté par un graphe orienté, composé de nœuds (états), il y a un état initial et des états finaux. 

En résumé, les expressions régulières permettent principalement trois grands types d’opérations :

-         Vérification d’une règle syntaxique ;

-         Remplacement d’un élément dans une chaîne par un autre ;

-         Extraire des entités dans une chaîne de caractères.


2 - Les expressions régulières

Nous allons tout d’abord commencer par un rappel sur les expressions régulières. Si vous découvrez les expressions régulières, ne vous inquiétez pas, vous devriez mieux comprendre au fur et à mesure votre progression dans cet article grâce aux exemples.

Une expression régulière définit des règles que doivent respecter une chaîne de caractères, par exemple pour vérifier d’une chaîne est contient un chiffre on lui appliquera le masque  « [0123456789] », c’est-à-dire qu’il doit contenir un des caractères entre les crochets, on pourra écrire plus simplement « [0-9] », c’est-à-dire un caractère de l’intervalle 0 à 9.

Il existe de nombreuses règles applicables sur une chaîne de caractères, en voici quelques-unes que je vais vous illustrer par des exemples. 

\

 Annule le sens d’un méta-caractère

^

 Début de ligne

.

 N’importe quel caractère

$

 Fin de ligne

|

 Alternative

()

 Groupement

-

 Intervalle de caractères

[]

 Ensemble de caractères

[^]

 Tous sauf un ensemble de caractères

 

Exemples : 

Ligne contenant un « a » ou un « b » : ^(a|b)$
Lettre minuscule comprise en « a » et « h » : [a-h] ou [abcdefgh]
Lettre comprise entre « a » et « h » majuscule ou minuscule : [a-hA-H]
Tous les caractères sauf les lettres majuscules : [^A-Z] 

Pour désigner un caractère spécial, ou méta-caractère, tel que le « ^ »  ou  « ] » il suffit que le faire précéder d’un anti-slash, dans cet exemple : « \^ » et  « \] ». 

Il est intéressant de pouvoir spécifier le nombre fois qu’apparaissent les caractères : 

*

 0 fois ou plus

+

 1 fois ou plus

?

 0 ou 1 fois

{n}

 n fois exactement

{n,}

 Au moins n fois

{n,m}

 Au moins n, mais maximum m fois


Exemples : 

Un mot de 4 à 7 lettres : [a-z]{4,7}
Au moins un « a » : a+ 

Voici quelques alias bien pratiques : 

\n

 

 Caractère de fin de ligne

\r

 

 Retour à la ligne

\t

 

 Tabulation

\s

[\f\n\r\t\v]

 Espacement

\S

[^\f\n\r\t\v]

 Tout ce qui n’est pas un espacement

\d

[0-9]

 Un chiffre

\D

[^0-9]

 Tout sauf un chiffre

\w

[a-zA-Z0-9_]

 Un caractère alphanumérique

\W

[^a-zA-Z0-9_]

 Tout sauf un caractère alphanumérique

\067

7

 Caractère en octal

\x5A

Z

 Caractère en hexadécimal

 

3 - Vérification d’une règle syntaxique 

Nous allons travailler avec la classe System.Text.RegularExpressions.Regex, celle-ci va nous permettre de vérifier si une chaîne respecte bien les règles d’une expression régulière. 

Dans l’exemple qui suit, nous allons vérifier que la chaîne maChaine est composée uniquement des lettres minuscules, c’est-à-dire qu’elle vérifie l’expression régulière « ^[a-z]+$ » 

using System;
using System.Windows.Forms;
using System.Text.RegularExpressions;  

namespace ExempleRegexp
{

      public class Exemple1
      {
            static void Main() 
            {
                  Regex   maRegexp = new Regex("^[a-z]+$");
                  string  maChaine = "Salut à tous !!";
                  bool    regOK    = maRegexp.IsMatch(maChaine);

                  if (regOK)
                        MessageBox.Show("ok");
                  else
                        MessageBox.Show("pas ok");
            }
      }
}  

La fonction isMatch retourne false, le message « pas ok » est donc affiché, puisque « Salut à tous !! » n’est pas composé uniquement de lettres minuscules, mais aussi d’une lettre majuscule, d’espaces et de signes de ponctuation. 

Remarque : Lorsque l’on est écrit une expression régulière en C#, celle-ci étant entre guillemets, il faudrait normalement précéder chaque anti-slash d’un autre anti-slash, ce qui assez lourd ! Mais il existe une solution mettre un @ devant la chaîne de caractères, par exemple : @"^[\w]+$"; 

4 - Identification d’éléments

Nous allons voir comment identifier des éléments dans une expression.

Une adresse email est composée deux parties séparées par un @, ces deux parties peuvent être composées de lettres, tirets, points c’est que j’ai représenté avec « [\w\-.]+ », en fait la partie serveur ne peut pas contenir d’underscore nous l’écrirons alors plutôt : [a-zA-Z0-9\-.]+. Comme précédemment nous allons vérifier qu’une chaîne de caractère respecte une expression régulière, mais nous allons en plus identifier des éléments dans cette chaîne,  pour cela nous allons les mettre entre parenthèses. 

using System;
using System.Windows.Forms;
using System.Text.RegularExpressions;  

namespace ExempleRegexp
{
      public class Exemple2 
      {
            public static void Main()
            {
                  Regex regEmail = new Regex(@"^([\w\-.]+)@([a-zA-Z0-9\-.]+)$");
                  string strEmail = "marc.falesse@supinfo.com";
                  Match monMatch = regEmail.Match(strEmail);
                  if (monMatch.Success) 
                  {
                        MessageBox.Show("Utilisateur: " + monMatch.Groups[1].Value);
            
                        MessageBox.Show("Serveur: " + monMatch.Groups[2].Value);
                 
                  else 
                        MessageBox.Show(strEmail + " n'est une adresse email valide !!");
            }
      }
}

Nous avons récupéré l’expression satisfaisant « ([\w\-.]+) » dans monMatch.Groups[1], et l’expression satisfaisant « ([a-zA-Z0-9\-.]+) » dans monMatch.Groups[2] !!

Mais il serait plus intéressant de donner des noms plus conviviaux à ces valeurs, c’est ce que j’ai fait dans cette version modifiée : 

Regex regEmail = new Regex(@"^(?<utilisateur>[\w\-.]+)@(?<serveur>[a-zA-Z0-9\-.]+)$");
string strEmail = "marc.falesse@supinfo.com";
Match monMatch = regEmail.Match(strEmail);
if (monMatch.Success)
{
     
MessageBox.Show("Utilisateur: " + monMatch.Groups["utilisateur"].Value);
      MessageBox.Show("Serveur: " + monMatch.Groups["serveur"].Value);          
}
else 
     
MessageBox.Show(strEmail + " n'est une adresse email valide !!");
}

Maintenant le « ?<utilisateur> » à l’ouverture de la parenthèse permet d’aliaser la valeur récupérée, on peut ici récupérer cette valeur avec monMatch.Groups["utilisateur"].Value ; De la même façon on peut récupérer la valeur aliasée monMatch.Groups["serveur"].Value. 

Remarque :  Si j’avais omis le « ^ » et le « $ » la procédure aurait trouvé une adresse email contenue dans la chaîne de caractères strEmail.


5 - Réaliser des remplacements 

Nous allons continuer à travailler avec la classe System.Text.RegularExpressions.Regex.

Nous allons remplacer la première occurrence du mot du mot « sympa » ou celle du mot « cool », par le mot « nulle » : 

Regex  regCool   = new Regex("(sympa|cool)");
string strSoiree = "C'était une soirée sympa !! Julie était cool !!";
MessageBox.Show(regCool.Replace(strSoiree, "nulle", 1));  

Le programme a remplacé « sympa » par « nulle », il a affiché : « C’était une soirée nulle !! Julie était cool !! »

Le troisième paramètre de la fonction Replace est facultatif, il correspond au nombre de remplacement à effectuer. Par défaut cette fonction remplacera toutes les expressions satisfaisant l’expression régulière. 

Une expression peut être fonction de l’expression qu’elle remplace.

Dans l’exemple qui suit allons voir que l’on peut récupérer les valeurs entre parenthèses. La première expression entre parenthèse prend la valeur $1, la seconde $2.

Nous allons ainsi inverser les deux premiers mots d’une chaîne : 

string strCool = "elle est sympa";
Regex  regCool = new Regex(@"^(\S+)\s+(\S+)");
M
essageBox.Show(regCool.Replace(strCool, "$2 $1"));  

Ici, on a demandé de remplacer l’expression « elle est » par « est elle ».  

Je vais conclure sur les remplacements, avec un exemple simple et pratique. Les expressions régulières utilisées ci-dessous, permettent de transformer un texte en HTML, en rendant cliquables ses liens http et ses emails : 

Regex  regURL = new Regex(@"(http://\S+)");
Regex  regEmail = new Regex(@"([\w\-.]+@[\w\-.]+)");

strHTML = regURL.Replace(strHTML, "$1");
strHTML = regEmail.Replace(strHTML, "$1");  

Cet exemple suppose que la chaîne strHTML soit préalablement initialisée. Comme dans l’exemple précédent, la chaîne de remplacement est fonction de la chaîne initiale ; Nous avons récupéré les valeurs entre parenthèses que nous avons exploitées avec $1. 

6 – Scinder une chaîne de caractères 

La fonction System.Text.RegularExpressions.Regex.Split() permet de faire comme la fonction  split() du Perl, ou explode() du PHP, c’est-à-dire qu’elle retourne un tableau de chaînes, chacune d'entre elle est une sous-chaîne de la chaîne initiale délimitée par les occurrences trouvées de l'expression régulière.

Dans l’exemple qui suit, nous allons afficher avec un MessageBox chaque élément séparé par une virgule ou un point-virgule, de la chaîne de caractères strMots.

Regex    regSepar = new Regex("[;,]");
string   strMots = "chat de gouttière,tortue d'eau douce,poisson d'avril";
string[] tabMots = regSepar.Split(strMots);

foreach (string mot in tabMots)
      MessageBox.Show(mot);   

Nous avons affiché un à un, chacun des mots qui était séparé par une virgule ou un point-virgule.
 

7 - Conclusion

 Les expressions régulières sont bien pratiques! Elles permettent de vérifier la validité des données entrées par l’utilisateur, par exemple dans une TextBox. Elles peuvent ainsi servir à vérifier la syntaxe d’un numéro de téléphone, un numéro ISBN, un numéro de carte bleue, une adresse email, une URL…

Ces expressions permettent également d’identifier dans éléments dans une chaîne, et donc de réaliser un parseur puissant.

Nous avons vu qu’il est également possible de remplacer un élément d’une chaîne, ou de scinder une chaîne en sous-chaînes.

Bref, pleins d’outils pratiques pour traiter les chaînes de caractères !

 

Commentaires
Par Peppy Hare 'PeppyHare' le 10/08/2006 17:52
J'ai un petit souci tout petit tout petit : '\t' ne produit pas l'effet attendu : tabulation...
que faire?

Par Peppy Hare 'PeppyHare' le 10/08/2006 18:15
Je précise que c'est dans un label de windows form

Ajouter un commentaire
Vous devez être authentifié pour poster un commentaire. Vous pouvez vous authentifier ici.

 

 

 
   
© Copyright SUPINFO - International University
Conditions dutilisation et Copyright - Respect de la vie prive
Labo Microsoft | Forum Microsoft | Forums .Net | Labo .Net | Blogs | FaqXP | Certifications
 
Créer un compte | Connexionmardi 2 décembre 2008