Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

LES EXPRESSIONS RATIONNELLES ("RÉGULIÈRES")


Information sur le tutorial

Catégorie :Texte Date de création : 14/09/2006 22:44:52 Vu : 12 845 fois

Note :
9 / 10 - par 8 personnes
9,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (28)
Ajouter un commentaire et/ou une note

Description

Ce tutoriel est une présentation détaillée des expressions rationnelles, un outil maniable et performant au service du programmeur dans les manipulations de chaînes de caractères.

Tutorial

Les expressions rationnelles ("régulières")   

Mise en mage partiellement restituée... la suite plus tard.

A. Qu'est-ce qu'une expression rationnelle ?


Tous les programmeurs disent du bien des expressions rationnelles. Pourtant, l'unanimité est assez rare dans le domaine. En fait, il y a une raison très simple à cela : elles sont à la fois maniables et performantes. Il serait donc dommage de s'en priver... Ce tutoriel vous propose donc d'aller y faire un petit tour. D'avance, je tiens à préciser que toutes les remarques, critiques, corrections et suggestions relatives à ce tutoriel sont les bienvenues. Je vous prie aussi de m'excuser pour les incohérences de mise en forme que vous pourriez rencontrer.

On entend presque toujours parler d'expressions régulières (ou de regexp, par contraction de l'anglais regular expressions). Pourtant, l'expression "expressions régulières" est un calque de l'anglais "regular expressions" : ce n'est pas une traduction correcte. On devrait plutôt parler d'expressions rationnelles. En maths, on parle d'ailleurs bien d'expressions rationnelles. En maths ? Hé oui ! Il n'y a pas d'erreur, vous avez bien lu. Ces expressions sont associées à des maths, même si ça ne se voit pas au premier coup d'oeil (pour en savoir plus, il faut aller chercher du côté de la théorie des automates et des langages formels). Mais rassurez-vous, je ne vais pas vous parler d'automates, même si c'est intéressant, et nous ne ferons pas de mathématiques !


B. Comment y accéder à partir de Visual Basic ?

Maintenant que les présentations sont faites, parlons un peu des expressions rationnelles avec Visual Basic. Pour les utiliser, cliquez sur le menu "Projet", puis sur l'onglet "Références". Dans la longue liste qui apparaît alors, cochez la ligne "Microsoft VBScript Regular Expressions 5.5". Voilà, c'est déjà terminé, vous pouvez vous en servir ! Certes oui... mais comment, me direz-vous ? C'est ce que nous allons apprendre maintenant...

Attention ! Pour tirer le meilleur parti de ce tutoriel, il faut que vous puissiez essayer vous-même les exemples que je vous propose. C'est la raison pour laquelle je vous conseille de vous servir du RegExp Workshop de Renfield : http://www.codes-sources.com/code.aspx?ID=17331. Avec cet outil et un peu de bonne volonté, tout devrait bien se passer.


C. Que faut-il déclarer ?

Pour utiliser les expressions rationnelles, trois variables suffisent. Dans un module, ajoutez donc :

Option Explicit
'Cette variable vous permet de paramétrer une expression rationnelle
Private oRegExp As RegExp
'Cette variable contient l'ensemble des occurrences trouvées dans un texte
'à partir de votre expression rationnelle
Private Results As MatchCollection
'Cette variable désigne un résultat particulier au sein de la structure précédente
Private Item As Match  

La variable oRegExp contient l'expression rationnelle, c'est-à-dire son motif, ses options et quelques fonctions, mais nous détaillerons tout cela plus tard. La variable Results désigne l'ensemble des morceaux de textes (les occurrences) qui satisfont les conditions définies dans le motif et les options de l'expression rationnelle. La variable Item, enfin, désigne une occurrence quelconque à l'intérieur de la collection d'occurrences Results. Pour ces trois variables, j'ai choisi une portée privée (limitée au module) mais vous pouvez tout aussi bien choisir une portée publique. Tout dépend naturellement de l'utilisation que vous souhaitez en faire. Pour ma part, je place généralement tout ce qui touche aux expressions rationnelles dans le même module (nommé mRegExp, ce qui n'est pas très original...), d'où mon choix.


D. Pourquoi pas Dim oRegExp As New RegExp ?

La variable oRegExp doit être déclarée et instanciée. Il est donc tout à fait possible d'écrire :

'Cette variable vous permet de paramétrer une expression rationnelle
Private oRegExp As New RegExp


C'est une écriture tout à fait correcte, mais contestable. Pourquoi ? Tout simplement parce qu'une variable qui utilise "New" est considérée par VB comme devant être auto-instanciée (cf. tutoriel sur l'optimisation avec VB6). De fait, vous vous exposez à des vérifications supplémentaires qui nuisent aux performances de votre programme (Attention ! Si vous faites un usage modéré des expressions rationnelles, vous ne sentirez pas la différence. Mais si vous êtes curieux de quantifier cette différence de temps d'exécution, tournez-vous vers les API QueryPerformanceCounter et QueryPerformanceFrequency. Il y a plusieurs bonnes source sur le sujet sur VBFrance. Je vous propose celle-ci : http://www.codes-sources.com/code.aspx?ID=39534).


E. Paramétrer l'expression rationnelle

Pour paramétrer une expression rationnelle, nous allons commencer par créer une fonction Initialize, qui aura pour rôle d'instancier la variable oRegExp, d'une part, et de définir plusieurs options de recherche, d'autre part :

Private Sub Initialize()   
    'Création d'une nouvelle instance de l'objet RegExp (inutile si vous
    'avez écrit "New" dans la déclaration)   
    Set oRegExp = New RegExp   
    With oRegExp      
        'Une recherche globale s'effectue sur la totalité du texte, sans
        's'arrêter dès le premier résultat trouvé      
        .Global = True
        'Le texte est-il considéré comme une seule et même ligne, ou comme
        'plusieurs lignes distinctes ?
        .Multiline = True
        'Tient-on compte de la différence entre majuscules et minuscules
        '(case sensitiveness) ou non (case insensitiveness) ?
        .IgnoreCase = True
        'Clef de voûte de notre expression rationnelle : son motif. Nous
        'en parlerons un peu plus loin
        .Pattern = "&H[\dA-F]{1,6}"
    End With
End Sub


  • Recherche globale : Lorsque la recherche est définie comme globale, le moteur poursuit son analyse jusqu'à la fin du texte. Dans le cas contraire, il cesse d'analyser le texte dès qu'une chaîne satisfait le motif d'expression rationnelle et les options associées.

  • Recherche multiligne : Lorsque la recherche est définie comme multiligne, le texte où s'effectue la recherche est considéré comme un ensemble de plusieurs lignes. Dans le cas contraire, il est considéré comme une seule et même ligne, le retour à la ligne étant alors traité comme un espace parmi d'autres. Ce paramètre influe sur les métacaractères ^ et $, mais nous le verrons plus tard.

  • Ignorer la casse : Si vous choisissez d'ignorer la casse, les majuscules et les minuscules seront considérées comme équivalentes. Dans le cas contraire, elles seront distinguées les unes des autres. C'est un peu ce qui se passe quand vous choisissez vbTextCompare plutôt que vbBinaryCompare.

Avant de nous intéresser au motif, ce qui constitue l'essentiel de ce tutoriel, créons rapidement deux autres fonctions : une fonction de libération de la mémoire, et une fonction de recherche des occurrences. Voici donc :

'Libération de la mémoire pour terminer le travail proprement
Private Sub Terminate()
    Set oRegExp = Nothing
    Set Results = Nothing
    Set Item = Nothing
End Sub


'Cette procédure possède une portée publique car nous allons l'appeler
'depuis une feuille (ou un autre module, etc...)
Public Sub Search( ByVal sText As String )
    'D'abord, il faut créer une instance et paramétrer l'expression rationnelle.
     Call Initialize
    'Ensuite, il faut lancer la recherche et récupérer tous les résultats
    '(variable Results, voir plus haut)
    Set Results = oRegExp.Execute(sText)
    'Ensuite, il faut agir sur les résultats. Je ne vous décris pas encore
    (cette partie, car nous en parlerons plus tard ! Patience :-)
    For Each Item In Results
       MsgBox "Couleur HTML valide : " & Item.Value
    Next
    'Tout bon travail finit proprement. Il est temps de libérer la mémoire !
    Call Terminate
End Sub



F. Créer un motif d'expression rationnelle

Attention ! Avant de commencer, il faut rappeler une distinction importante. Les expressions rationnelles mettent à votre disposition un puissant outil de contrôle de validité syntaxique. Cela signifie que vous pouvez savoir si quelque chose est "bien écrit". En fait, les expressions rationnelles travaillent sur la forme, pas sur le fond. Ainsi, il est vrai que sofjgkfpzjebeoa@free.fr représente une adresse électronique syntaxiquement correcte, mais rien ne prouve qu'elle est réelle et attribuée à quelqu'un (si tel était le cas, ce dont je doute, mais bon... je tiens d'avance à m'exuser auprès de la personne malchanceuse... et farfelue (!) qui possède cette adresse). Maintenant que vous savez tout ça, nous pouvons entrer dans le vif du sujet.

Nous allons apprendre un créer un motif d'expression rationnelle. Démystifions la chose tout de suite : un motif (mot anglais : pattern) est une chaîne de caractères (type String). La seule différence ( Attention ! Il n'y en a qu'une, mais elle est importante) entre une chaîne de caractères traditionnelle et un motif d'expression rationnelle, c'est que les caractères qui les composent n'ont pas le même sens. Dans une chaîne de caractères traditionnelle, le sens du caractère est le "sens courant". Par exemple, "[]" sont de simples crochets, "{}" de simples accolades, "." un point sans prétention, "\d" un antislash suivi de la lettre d, "+" le signe de l'addition, et ainsi de suite... En revanche, dans un motif d'expression rationnelle, certains caractères possèdent un "sens différent" qui leur permet de décrire la disposition des caractères de "sens courant". Créer un motif d'expression rationnelle consiste à abstraire un cas particulier pour obtenir... un cas général, dans lequel entrent tous les cas particuliers ! C'est la raison pour laquelle certains caractères changent de sens et aquièrent un statut différent des autres. Ce sont des caractères "de niveau supérieur"... des métacaractères (voilà, le mot est jeté !). Si vous voulez une comparaison, imaginez un peu que j'entreprenne de vous présenter l'anglais. Je pourrais écrire "La phrase good morning sert à souhaiter le bonjour en début de journée". Dans cet exemple, on distingue un langage décrit (l'anglais), et un métalangage descriptif (le français). C'est un peu pareil avec les expressions rationnelles. Les caractères "classiques" sont décrits par des caractères promus à un "niveau supérieur", avec un sens nouveau, qui en fait des métacaractères.


G. La syntaxe d'un motif d'expression rationnelle


Considérez par exemple une couleur HTML classique. Si je vous demande de m'écrire une exemple de ce type de couleur, vous me proposerez peut-être quelque chose du genre "&HF0C01B". Ce n'est pas un très bon exemple, parce qu'il pourrait laisser croire à quelqu'un qui ne connaît pas les couleurs HTML qu'une couleur de ce type comporte toujours six chiffres. Or il est possible d'écrire "&HAB". Finalement, aucun exemple ne couvre tous les cas de figure. Il est plus judicieux de se demander ce qu'est une couleur HTML en tant que telle (hé oui, c'est comme Socrate qui demande ce qu'est la vertu, et à qui on donne en réponse des exemples de vertus, et pas la définition de la vertu dans le cas général). Dans ce domaine, les expressions rationnelles vont nous aider. Enfin... elles ne font pas tout quand même. Nous avons un peu de culture, nous savons qu'une couleur HTML est une valeur compris entre 0 et FFFFFF en notation hexadécimale, précédée de &H. Hé bien, voilà une bonne définition ! Il ne reste plus qu'à traduire cette phrase dans un langage accessible à l'ordinateur : un motif d'expression rationnelle. Pour cela, nous allons suivre une progression en douze points (hé oui, tant que ça !) :

1. Les métacaractères
2. Les quantificateurs
3. Les intervalles de reconnaissance
4. Les classes de caractères
5. Les classes complémentées
6. Les classes génériques
7. Masques et alternatives
8. Les assertions simples
9. Les assertions complexes
10. Les ancrages
11. Capturer des portions d'occurrences
12. Retour sur les quantificateurs : la gourmandise

Attention ! La liste paraît impressionnante... mais vous verrez que l'on en vient vite à bout. Après, quand la syntaxe vous sera devenue familière, cela vous paraîtra même "assez court". Evidemment, la première fois, ce n'est jamais facile. Et ce n'est rien que de bien normal !


1. Les métacaractères

Les métacaractères, comme je l'ai expliqué tout à l'heure, sont des caractères qui ont un sens particulier. Evidemment, à cause de ce sens supplémentaire, ils ne peuvent pas être employés n'importe comment. En particulier, vous vous doutez qu'il ne sera pas possible de les employer comme caractères classiques sans leur ajouter quelque chose pour les différencier de leur utilisation en tant que métacaractères. Mais en attendant, voici déjà une liste bien fournie (mais pas encore exhaustive, il en manque quelques-uns, ce sera pour une prochaine mise à jour) : Attention ! Ne prenez pas peur si vous trouvez plein de mots barbares ci-dessous. Nous allons revenir très longuement sur chacun d'entre eux. C'est promis, vous saurez tout (enfin presque tout...) mais pas tout de suite ! Pour l'instant, contentez-vous de savoir que ce sont des métacaractères.

"^"
Placé en début de motif, il signifie "début de la ligne". Placé après un crochet ouvrant, il définit une classe complémentée.

"$"
Comme métacaractère, toujours placé en fin de motif. Il signifie "fin de ligne"

"[" et "]"
Les crochets (ouvrant et fermant) délimitent les classes.

"(" et ")"
Les parenthèses (ouvrante et fermante) délimitent les masques et les alternatives.

"{" et "}"
Les accolades (ouvrante et fermante) délimitent les intervalles de reconnaissance.

"."
Le point remplace n'importe quel caractère, à l'exclusion d'un retour à la ligne.

"?", "*" et "+"
Quantificateurs. Le point d'interrogation possède deux autres sens (suppression de la gourmandise, suppression de la capture)

"|"
Séparateur des différents choix d'un masque ou d'une alternative (c'est l'union ensembliste chère aux matheux !).

"\"
Introduit une classe générique ou un ancrage. Egalement très utile pour séparer un caractère d'un métacaractère. Voici une question que j'abordais déjà au début de ce paragraphe : Comment faire pour employer ces métacaractères dans leur "sens normal", c'est-à-dire comme de simples caractères ? La réponse est très simple, il suffit de les faire précéder d'un antislash. Par exemple, "\+" désigne le caractère "+" et non le métacaractère "+", en raison de la présence de l'antislah (sauf erreur, c'est aussi de cette façon que l'on indique, en C, un guillemet dans une chaîne de caractères, en écrivant \". Enfin, bon, on ne parle pas de C ici, donc laissons tomber cet exemple). Attention ! Il existe des exceptions. Gardez ça dans un coin de votre mémoire, car je ne l'ai pas écrit ici (ça fait appel à des notions que nous n'avons pas encore abordées). Mais je n'oublierai pas de vous le dire par la suite.


2. Les quantificateurs

Les quantificateurs, comme leur nom l'indique, permettent de dénombrer des caractères. Imaginez un peu les quantificateurs en anglais : some, any et no. Ce que nous allons faire, c'est à peu près la même chose, sauf que nous allons utiliser des symboles, et rendre la chose un peu plus rigoureuse.

? signifie "au plus une occurrence" (c'est-à-dire rien ou une occurrence)
    Exemple : Le motif "a?" permet de décrire exclusivement "a" et "" (la chaîne vide)

* signifie "rien, une ou plusieurs occurrences"
    Exemple : Le motif "a*" permet de décrire entre autres "" (la chaîne vide), "a", mais aussi "aa", "aaa", "aaaa", etc...

+ signifie "au moins une occurrence" (c'est-à-dire une ou plusieurs occurrences)
    Exemple : Le motif "a+" permet de décrire entre autres "a", "aa", "aaa", "aaaa", etc..., mais pas la chaîne vide

# Observation pour conclure :
Tous les quantificateurs sont postfixés, c'est-à-dire qu'ils suivent le caractère auquel ils s'appliquent.


3. Les intervalles de reconnaissance


Bon, vous avouerez que, jusqu'à présent, nous avons dénombré les occurrences de façon assez grossière : absence, unité ou répétition. Avec les expressions rationnelles, nous allons pouvoir aller plus loin et utiliser des entiers. C'est ce que l'on appelle les intervalles de reconnaissance :

{n} signifie "exactement n occurrences"
    Exemple : Le motif "a{3}" permet de décrire la chaîne "aaa", et rien d'autre !

{n, p} signifie "entre n et p occurrences"
    Exemple : Le motif "a{1, 3}" permet de décrire les chaînes "a", "aa" et "aaa"

{n,} signifie "au moins n occurrences"
    Exemple : Le motif "a{5,}" permet de décrire les chaînes "aaaaa", "aaaaaa", "aaaaaaa", etc...

# Observation pour conclure :
Ici aussi, les intervalles de reconnaissance sont postfixés.


4. Les classes de caractères

Les classes de caractères sont délimitées par des crochets. A l'intérieur de ces crochets se trouvent des caractères ou des intervalles de caractères (les caractères extrêmes sont alors reliés entre eux par un trait d'union). Par exemple :

[a-z] signifie "tout caractère entre a et z (toute lettre de l'alphabet latin)"
    Exemples : "[a-z]+" permet de décrire "bonjour", "a", "et", etc..., mais pas la chaîne vide (à cause du quantificateur "+")                     

"[ziag]*" permet de décrire "zigzag", "z", "ai", "" (la chaîne vide), etc..., mais pas "ah" (car "h" n'est pas un élément de "[ziag]")
"[rdvls]i[sxz]e?" permet de décrire "ris", "riz", "rixe", "dis", "dix", "dise", "vis", "vise", "lis", "lise", "sis", "sise", "six".
[0-9] signifie "tout chiffre compris entre 0 et 9"    Exemple : "[0-9]?" permet de décrire "1", "8", "9", "" (la chaîne vide), etc.., mais pas "21" (à cause du quantificateur "?")

Plus généralement : [c(1)c(2)...c(n)] signifie "qui comporte un caractère au choix parmi c(1), c(2), ..., c(n)" Attention ! Si vous avez choisi de tenir compte de la casse (via oRegExp.IgnoreCase = False pour ceux qui auraient oublié), sachez que [a-z] diffère de [A-Z].

Remarque : Si vous souhaitez indiquer les intervalles a-z et A-Z, n'écrivez pas [A-z] sous prétexte que les majuscules viennent avant les minuscules dans le code ASCII. Il ne faut pas oublier que, sans vous en rendre compte, vous ajouteriez aussi la plage ASCII comprise entre (90 désigne "Z") 91 et 96 (97 désigne "a"), qui ne correspond pas à des caractères alphabétiques ! Evitez donc ces fantaisies et écrivez plutôt [a-zA-Z]. N'écrivez pas non plus des choses comme [aA-zZ] ou autres, qui n'ont évidemment pas le même sens.

Attention ! Vous avez vu que le trait d'union sert à désigner un intervalle de caractères (par exemple dans "[a-z]"). Pour l'utiliser en tant que trait d'union, il faut le placer en début de classe. Par exemple "[-a-z]" équivaut à "trait d'union et lettres de l'alphabet".


5. Les classes complémentées

Les classes complémentées sont des classes dans lesquelles vous indiquez non pas les caractères à rechercher, comme nous l'avons fait précédemment, mais ceux qu'il faut au contraire exclure des résultats. Ce sont aussi des ensembles de caractères mais, cette fois-ci, les occurrences retenues se composent de caractères qui ne sont pas éléments de l'ensemble.

[^a-z] signifie "tout caractère non compris entre a et z (autre qu'une lettre de l'alphabet)"
    Exemple : Le motif "[^aeiou]+" permet de décrire "pff", "pst", "grrr", mais pas "oh" (car le "o" est exclu : c'est une voyelle)

[^0-9_] signifie "qui ne comporte ni chiffre ni underscore"
    Exemple : Le motif "[^2-9_]{1,2}" permet de décrire "34", "8", etc.. mais pas "20" (zéro exclus) ou "234" (pas plus de deux caractères)

Plus généralement : [^c(1)c(2)...c(n)] signifie "qui ne comporte aucun des caractères c(1), c(2), ..., c(n)"

Attention ! Mêmes remarques que précédemment.
Attention ! Vous vous souvenez ? Je vous avais dit de garder quelque chose dans un coin de votre mémoire... hé bien, nous y sommes ! Le crochet fermant et le trait d'union sont deux métacaractères. Ils gardent leur statut de métacaractère dans une classe, mais sont considérés comme de simples littéraux en dehors de celle-ci. Conclusion : en déhors d'une classe, il est inutile d'écrire "\]" ou "\-" avec un antislash.


6. Les classes génériques

Les classes génériques sont des classes prédéfinies (car très souvent utilisées). Il vous est donc inutile d'utiliser les classes de caractères et les classes complémentées correspondantes. Sachez cependant que cela ne provoquerait aucune erreur.

"\w" (w pour word) correspond à la classe de caractères "[a-zA-Z0-9_]"
"\d" (d pour digit) correspond à la classe de caractères "[0-9]"
"\W" (w majuscule pour (not a) word) correspond à la classe complémentée "[^a-zA-Z0-9_]"
"\D" (d majuscule pour (not a) digit) correspond à la classe complémentée "[^0-9]"
"\xn" avec n un entier en hexadécimal correspond à une valeur du code ASCII. Par exemple, Asc("A") = 65 et 65 = &H41 d'où "\x41" désigne A !


7. Masques et alternatives

Jusqu'à présent, nous avons vu comment inclure plusieurs caractères, mais nous ne nous sommes pas souciés de leur ordre. En effet, l'ordre d'apparition des caractères dans les classes est sans importance. Si vous souhaitez créer une structure où l'ordre des caractères est important, il faut utiliser des masques. Prenons un exemple :

"fran(ce|co|c)" correspond exclusivement à l'un des trois mots suivants : "franc", "france", "franco"
En revanche "fran[ceo]{1,2}" correspond à "franc, frane", "frano", "france", "franeo", "franco", etc...

Plus généralement : (séquence(0)|séquence(1)|...|séquence(n)) permet d'obtenir la séquence(0) ou la séquence(2) ou ... ou la séquence(n) avec respect de l'ordre des caractères. De plus, comme vous l'avez vu, vous pouvez définir des séquences de longueur différente.


8. Les assertions simples

Les assertions sont des contraintes imposées au moteur de recherche. Elles ne décrivent pas des caractères mais indiquent une zone de recherche. En gros, elles vous permettent de parler de "début de ligne", de "fin de ligne", de "limites de mots", etc... Ce sont :

"^". Placé en tout début de motif, il signifie "au début d'une ligne"
    Exemple : "^A.*" permet de rechercher toutes les lignes qui commencent par la lettre majuscule A ("A" tout seul, ou encore "Ah le bel exemple")

 "$". Placé tout à la fin du motif, il signifie "à la fin de la ligne"
    Exemple : ".*t$" permet de rechercher toutes les lignes qui finissent par la lettre minuscule t ("t" tout seul, ou "Enfin un exemple concret")

"\b". Cette assertion permet de désigner "une limite de mot"
    Exemple : "^.*bon\b.*$" permet de décrire "un bon exemple" mais pas "le bonheur" car bon n'est plus suivi d'une limite de mot, mais d'un "h"

"\B". cette assertion permet de désigner "ce qui n'est pas une limite de mot"
    Exemple : "^.*bon\B.*$" permet de décrire "le bonheur" mais pas "un bon exemple qui ne l'est plus" car bon est suivi d'une limite de mot


9. Les assertions complexes

Les assertions complexes ne sont pas très difficiles à comprendre, malgré leur nom.

(?:) Transforme des parenthèses normales en parenthèses non capturantes
(?=) Assertion avant positive (en anglais : positive lookahead)
    Exemple : Soit la chaîne "Un bel exemple que celui-ci !". On applique le motif "bel\s(?=exemple)". Une occurrence est trouvée car "bel" est suivi de "exemple".
    A l'inverse, si on applique ce même motif à la chaîne "Un bel oiseau sur la branche", aucune occurrence ne sera trouvée.

(?!) Assertion avant négative (en anglais : negative lookahead)
    Exemple : Soit la chaîne "Un autre bel oiseau !". Le motif "bel\s(?!exemple)" donne une occurrence car bel n'est pas suivi de "exemple"
    A l'inverse, si on applique ce même motif à la chaîne "Un bel exemple", aucune occurrence ne sera trouvée.

(?<=) Les assertions arrière positive (en anglais : positive lookbehind) et arrière négative (en anglais negative lookbehind) ne sont malheureusement pas accessibles avec Visual Basic 6. Sauf erreur, les expressions rationnelles obtenues ne sont pas considérées comme valides. A vérifier quand même... dans une prochaine mise à jour


10. Les ancrages

"\n" désigne une nouvelle ligne. C'est la syntaxe habituelle dans de nombreux langages (comme le C, le Caml, etc...). "\r" désigne un retour chariot. Pour ceux qui ne le sauraient pas (je ne sais pas s'il y en a... mais bon je n'en suis pas à quelques mots près) : le retour chariot, Chr(13), "symbolise" ce qui se passait jadis (oh, ce n'est pas non plus du temps de Cro Magnon !) quand on utilisait une machine à écrire. Pour aller à la ligne, il fallait tourner la molette et ramener le chariot en position initiale. C'est ainsi que, sous Windows, les retours à la ligne sont de type vbCrLf, avec vbCr le retour chariot (ou Chr(13)), et vbLf (ou Chr(10)) le retour à la ligne proprement dit. Attention toutefois à ne pas dire que vbCrLf et vbNewLine sont une seule et même chose car ce n'est pas vrai avec tous les systèmes d'exploitation. C'est vrai sous Windows, mais faux sous Linux, où vbNewLine se confond avec vbLf (absence du retour chariot vbCr). "\s" (s pour space) désigne un espace blanc. Il peut s'agir d'une tabulation ("\t"), d'un espace ("\f"), d'un retour à la ligne ("\n") ou d'un retour chariot ("\r") "\S" (s majuscule pour (not a) space) représente tout ce qui n'est pas un espace blanc. On peut lui trouver un équivalent sous la forme de la classe complémentée [^\t\r\n\f].


11. Capturer des portions d'occurrences

Remettons les choses au clair. Lorsque vous appelez la méthode Execute, vous récupérez un jeu (une collection) de résultatssous la forme d'un objet de type MatchCollection (notre variable Results). Chaque résultat contenu dans l'objet MatchCollection est une occurrence, représentée par un objet de type Match (notre variable Item). Seulement, vous souhaitez peut-être diviser chacune de ces occurrences en plus petites unités. C'est ici qu'interviennent les parenthèses. Considérez par exemple le motif suivant :

"\w+\d{2}"

Si nous voulons obtenir séparément le texte et les chiffres, nous écrirons plutôt :

"(\w+)(\d{2})"

L'ajout de parenthèses indique que nous souhaitons découper les occurrences en petites unités. Ces sous-résultats sont appelés des SubMatches. Ce ne sont pas des objets, contrairement à Match et MatchCollection. Ce sont de simples chaînes de caractères. Pour les obtenir à partir d'une variable de type Match, on peut utiliser deux syntaxes (même si, en fait, l'une des deux doit être préférée). La première, la moins bonne, est :

'Variable destinée à recevoir les sous-résultats
Dim sSubItem As Variant
For Each sSubItem In Item
    MsgBox sSubItem
Next


 Je réprouve cette écriture car elle nécessite une variable de type Variant (comprendre : fantaisiste et pas vraiment typée), alors qu'il n'y a aucune ambiguïté puisque tous les sous-résultats sont de type String. Comme il n'y a aucune raison d'écrire de telles choses, il vaut mieux préférer :

'Index des sous-résultats
Dim k As Long
For k = 0 To Item.SubMatches.Count
    MsgBox Item.SubMatches(k)
Next


Attention ! Capturer des portions de texte (autrement dit : créer des SubMatches) est une opération coûteuse dont il convient de ne se servir que lorsqu'elle est vraiment utile (d'ailleurs, même si elle ne l'était pas, par principe, on ne programme pas quelque chose qui ne sert à rien). Si vous souhaitez utiliser des parenthèses dans un motif sans que le moteur d'expressions rationnelles ne capture le texte pour autant, placez "?:" (un point d'interrogation suivi du signe de ponctuation deux points) directement après la parenthèse ouvrante. Par exemple :

Le motif "<<b>([a-z]+|[0-9]{2,3})>" capture un sous-résultat correspondant au motif [a-z]+|[0-9]{2,3}
Le motif "<<b>(?:[a-z]+|[0-9]{2,3})>" ne capture aucun sous-résultat.


12. Retour sur les quantificateurs : la gourmandise

Vous en savez maintenant assez pour que j'aborde une nuance soigneusement cachée jusqu'à présent... La gourmandise. Non, je ne veux pas vous parler de notre rapport à la nourriture :-). Les quantificateurs + et * sont "gourmands". Cela signifie qu'ils vont toujours chercher à trouver la plus longue chaîne possible. Par exemple, imaginons une page fictive du réseau Codes-Sources, où se trouverait le code HTML suivant :

<http://www.codes-sources.com/code.aspx?ID=999999>Ghost page</xxx>

Admettons que nous cherchions à récupérer l'adresse de la page de code (fictive... heureusement qu'il n'y a pas autant de sources sur VBFrance !). Nous pourrions élaborer le motif suivant : "<(.+)>".
Attention ! On peut proposer d'autres motifs plus précis qui éviteraient le problème que je vais soulever... mais l'intérêt serait alors nul ! J'ai proposé ce motif simpliste dans un but bien particulier. Ne me dites donc pas qu'on pouvait faire autrement et contourner ainsi le problème.

Revenons à notre sujet. En appliquant le motif (simpliste) au texte précédent, nous obtenons un objet MatchCollection contenant un élément Match tel que :

Item.Value = "<http://www.codes-sources.com/code.aspx?ID=999999>Ghost page</xxx>"
Item.SubMatches(0) = "http://www.codes-sources.com/code.aspx?ID=999999>Ghost page</xxx"

Oh ! Ce n'est pas du tout ce que nous voulons. Pourquoi ? Tout simplement parce que le plus long résultat ne s'arrête pas au premier symbole ">" puisqu'il en existe un autre plus loin. C'est ce comportement que l'on appelle la gourmandise. Alors, comment y remédier. Facile ! Ajoutons un point d'interrogation de la façon suivante : "<(.+?)>"

Maintenant, effectuons un nouvel essai.
Que trouvons-nous ? Que du bonheur...

Item.Value = "<http://www.codes-sources.com/code.aspx?ID=999999>Ghost page</xxx>"
Item.SubMatches(0) = "http://www.codes-sources.com/code.aspx?ID=999999"

Conclusion : Si vous souhaitez que les quantificateurs cessent de chercher l'occurrence la plus longue, et se bornent à la première séquence conforme, il vous faut remplacer les versions gourmandes * et + par leurs équivalents non gourmands *? et +?. A ce propos, notez que le point d'interrogation est polysémique ! Placé après un caractère, c'est un quantificateur. Placé après un quantificateur, il supprime la gourmandise... Et ce n'est pas tout ! Nous verrons par la suite qu'il possède un troisième sens (pour les impatients, allez voir "L'objet Match" et la rubrique "Attention !")... 


Les autres commandes

Nous avons vu qu'il existait une commande Execute grâce à laquelle il était possible de trouver toutes les occurrences d'un motif. Vous disposez également de deux autres commandes qui peuvent se révéler utiles :

'Existe-t-il au moins une occurrence du motif ?
Dim bCanFindSomething As Boolean bCanFindSomething = ORegExp.Test(sText)
'Remplacer les occurrences par un autre texte
Dim sReplace As String, sNewText As String
'Affectation : vous pouvez mettre ce que vous voulez !
sReplace = "New !"
'Le résultat de la fonction Replace n'est autre que le nouveau texte, après les remplacements
sNewText = ORegExp.Replace(sText, sReplace) 
 


MatchCollection et Match dans le détail


L'objet MatchCollection


Attention ! Souvenez-vous que "Results" est une variable objet de type MatchCollection définie tout au début de ce tutoriel. Je n'ai pas repris sa déclaration ici. Nous avons vu que les variables MatchCollection contiennent l'ensemble des résultats obtenus après exécution d'une commande Execute. Vous disposez de deux méthodes :

       'Dénombrer le nombre d'occurrences
       Dim ItemCount As Integer
       ItemCount = Results.Count

Ceci vous sera utile après la recherche, pour savoir si quelque chose a été trouvé.
       For k = 0 To Results.Count - 1
             'Sélection d'un résultat
             Set Item = Results.Item(k) ou Set Item = Results(k)
            ...
       Next

La méthode Item vous permet d'accéder à un résultat particulier à partir de son index (compris entre 0 et Results.Count - 1). Cependant, une telle boucle ne devrait pas être priviligiée, car elle est moins rapide que son équivalent For Each ( Attention ! Encore une fois, c'est une question d'optimisation. Il n'y a pas de différence flagrante pour une utilisation modérée des expressions rationnelles. Cependant, si vous prenez l'habitude d'utiliser la deuxième structure, ça ne nuira pas à votre code...) :

       For Each Item In Results
            ...
       Next


L'objet Match

L'objet Match est plus riche que le précédent. Il vous permet en effet d'obtenir plusieurs choses relativement intéressantes. Attention ! Souvenez-vous que "Item" est une variable objet de type Match définie tout au début de ce tutoriel (je sais, ça fait longtemps...). Je n'ai pas repris sa déclaration ici.

       'Obtenir le texte de l'occurrence
       Dim sItemText As String
       sItemText = Item.Value
       'Obtenir la longueur de l'occurrence
       Dim lItemLength As Long
       lItemLength = Item.Length

Remarque : Cela revient exactement à calculer Len(sItemText) où sItemText désigne la variable précédemment définie... mais c'est aberrant. Il est inutile de refaire ce qui a déjà été fait !

       'Index de la première occurrence dans le texte d'origine
       Dim lFirstIndex As Long
       lFirstIndex = Item.FirstIndex


Un exemple concret : les adresses électroniques

Suite à une remarque de Econs, je vous propose maintenant d'appliquer ce que nous avons vu dans ce tutoriel en proposant un motif d'expression rationnelle pour des adresses électroniques. Pour cela, il faut d'abord se demander ce qui définit une adresse électronique. Il s'agit :

1. Du nom choisi par l'utilisateur (pierre_6, paul12, etc...)
2. Du nom du fournisseur d'accès à internet (free, yahoo, etc... et je ne fais pas de publicité !)
3. Du type (fr, com, etc...)

On admet généralement que le nom d'utilisateur peut comporter n'importe quelle lettre de l'alphabet. En revanche, les chiffres, le point et l'underscore ne sont pas admis qu'à partir du second caractère. Sinon, pour le nom du fournisseur d'accès à internet, ainsi que pour le type, nous allons nous simplifier le travail et considérer que tout élément de la classe générique \w (petit rappel : [a-zA-Z0-9_] est accepté. Voici ce que ça donne, en plusieurs étapes :

a) Nom d'utilisateur
       Le premier caractère est toujours une lettre : [a-z]
       Le (les) autre(s) caractère(s), s'il(s) existe(nt), autorisent aussi le point, l'underscore et les chiffres : [\w\.]*
             -> Le \w désigne la classe générique word déjà vue plus haut
             -> \. désigne le point en tant que point, et non en tant que métacaractère.
             Rappelez-vous : il faut un antislash, sauf hors d'une classe pour le crochet fermant et le trait d'union.
             -> * est un quantificateur qui autorise : absence (pas de caractère), unité (un caractère) ou multiple (plusieurs caractères).      

Résumon-nous : Le nom d'utilisateur s'exprime grâce à [a-z][\w\.]*

b) L'arobas (ou arobase, ou arrobe...)
       C'est d'une intense difficulté :-). La bonne réponse est @

c) Le nom du fournisseur
       On simplifie la tâche en disant simplement \w+
       Le + est utile parce que les fournisseurs ne choisissent jamais la chaîne vide comme nom !

d) Le point (hé oui il y a un point entre le nom du fournisseur et le type !)
      On ne veut pas le métacaractère mais le caractère donc \.

e) Le type
      Comme précédemment.

L'heure est à la simplicité : \w+Conclusion : Dormez tranquilles. On ne remplira plus vos formulaires avec des adresses électroniques syntaxiquement incorrectes. Utilisez "[a-z][\w\.]*@\w+\.\w+". Maintenant, peut-être voulez-vous capturer le nom, le nom du fournisseur et le type séparément ? Pas de problème ! Utilisez des parenthèses capturantes : "([a-z][\w\.]*)@(\w+)\.(\w+)". Et puis, dernière chose pour finir, n'oubliez pas de ne pas tenir compte de la casse (oRegExp.IgnoreCase = True ).


Perspectives

Quoi de plus naturel que de terminer un tutoriel par quelques idées de programmes ou d'algorithmes en rapport avec les expressions rationnelles ? En vrac, voici quelques idées qui me viennent à l'esprit. La liste ne prétend évidemment pas à l'exhaustivité !

1. Comptes de messagerie (serveurs, adresse)
2. Extraction "avancée" de données à partir d'un tableau, d'une page web
3. Coloration syntaxique de code source (à la volée avec RichTextBox et SendMessage)
4. Jeux de lettres tels que Scrabble, anagrammes, dictionnaire, etc.
5. Tellement d'autres choses encore...


Conclusion

Vous voici au bout de vos peines... du moins en théorie. Maintenant que vous savez comment rédiger un motif d'expression rationnelle, et utiliser l'outil mis à votre disposition sous Visual Basic, il ne vous reste plus qu'à vous entraîner pour prendre vos marques et acquérir une certaine aisance. Courage, le plus dur est fait ! Et puis... tout ceci méritait bien les efforts que vous avez fournis : grâce aux expressions rationnelles, vous regarderez d'un autre oeil les Left, Right et autres Mid !
15 septembre 2006 13:43:25 :
Ajout du paragraphe "Un exemple concret : les adresses électroniques", ainsi que quelques corrections de mise en forme.
20 avril 2007 18:09:51 :
Mise en forme
09 novembre 2007 20:51:09 :
Restitution de la mise en forme
signaler à un administrateur
Commentaire de econs le 15/09/2006 11:35:17 administrateur CS

Salut,

Franchement bien foutu. Un seul petit regret : ne pas avoir utilisé d'exemple de reconnaissance d'adresse email valide, car c'est tout de même l'utilisation la plus fréquente des expressions régulières. Les gens viendront voir ton tutorial principalement pour çà.

Perso, je les utilise également pour du traitement de logs, du remplacement de caractères (quand le mot à remplacer peut prendre plusieurs formes), ... Bref, c'est vraiment un outil magique.

Hormis pour la déclaration des objets (évidemment), le tutorial peut-être repris tel quel pour des RegExp sous Javascript, Perl, ...

signaler à un administrateur
Commentaire de Cacophrene le 15/09/2006 12:46:21

Salut !

Merci pour le commentaire et la note. Je vais ajouter cet exemple ou même le substituer à celui des couleurs HTML (pas très parlant il est vrai). J'en profite aussi pour corriger quelques problèmes de mise en forme (retour à la ligne inutile, paragraphes collés, etc...). Rien de bien méchant mais comme c'est assez long, il vaut mieux que ce soit présenté correctement.

Cordialement,
Cacophrène

signaler à un administrateur
Commentaire de econs le 15/09/2006 16:09:49 administrateur CS

Oui, sur ton autre tuto il y a également quelques retours à la ligne qui foirent. Pas bien grave, suffit de baisser un peu les yeux et on trouve le reste de la phrase :o)

signaler à un administrateur
Commentaire de econs le 20/09/2006 09:32:37 administrateur CS

Quelle réactivité dans la modification du tuto ! Chapeau !

signaler à un administrateur
Commentaire de ABL-Online le 20/09/2006 19:08:50

Question validation d'adresse e-mail , j'utiliserais plutot ceci :

/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i

Cette expression à le mérite d'utiliser la norme RFC +- complète

Salutations,

Didier Lombet

signaler à un administrateur
Commentaire de ABL-Online le 20/09/2006 19:23:15

Petite erreur sorry

Correction :

^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$

et

/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/   [pour du javascript uniquement]

:$

Salutations

signaler à un administrateur
Commentaire de Cacophrene le 21/09/2006 09:30:49

Salut !

D'accord pour le motif complet. Mais pour des débutants (ce tutoriel s'adresse aux débutants), il est inutile d'aller chercher la norme RFC. Là c'était un exemple qui se voulait simple et aussi concret que possible pour manipuler les expressions rationnelles. Mais je prends note de ce que tu proposes.

Cordialement,
Cacophrène

signaler à un administrateur
Commentaire de ABL-Online le 21/09/2006 21:56:12

C'est vrai , tu as tout à fait raison , restons le plus simple possible et surtout compréhensible dans un tuto ;)

Cordialement,

Didier Lombet
Hostonet

signaler à un administrateur
Commentaire de DLink le 19/10/2006 18:36:53

Tres bon tuto, il est claire et complet et les exemples ne font pas de mal.

Je trouve juste un peu dommage d'avoir sauté la partie theorie des langages et automates qui me semble être la base de la comprehension des expressions rationelles, même si ca peut en dégouter certain.

Enfin ceci dit c'est un excellent travail qui a été réalisé encore bravo !

signaler à un administrateur
Commentaire de Cacophrene le 03/12/2006 11:31:22

Salut !

@ DLink : Merci pour ton commentaire. Pour la partie théorique, il me semble qu'elle relève plus d'une page d'encyclopédie ou d'un cours que d'un tutorial, qui se doit avant tout d'être pratique et efficace. Et puis, comme tu le dis, ça pourrait en dégoûter quelques-uns, qui cherchent seulement à faire marcher les regexp avec VB.


Cordialement,
Cacophrène

signaler à un administrateur
Commentaire de scoubigee le 07/12/2006 16:17:19

Chouette tutorial, pour moi les expressions régulières tenaient plsu de la magie noire qu'autre chose, désormais je comprends !

Très bien fait, j'en avais aps trouvé de mieux sur le net !

pour le mail j'en utilisais de toute faite, désormais je m'amuse à en créer pour mes besoins !

Merci !

signaler à un administrateur
Commentaire de Renfield le 11/12/2006 23:11:02 administrateur CS

tutoriel très bien fait...


pour ceux qui veulent tester et mettre au point des expressions régulières :
http://www.vbfrance.com/code.aspx?ID=17331

signaler à un administrateur
Commentaire de Cacophrene le 17/12/2006 16:51:08

Salut !

Merci pour vos remarques.

@Renfield : je me suis permi de mettre le lien vers ton programme dans le tutoriel lui-même parce que c'est vraiment un allié précieux, surtout quand les expressions commencent à être longues.

Encore merci à tous !

Cordialement,
Cacophrène

signaler à un administrateur
Commentaire de Little_Dev le 16/01/2007 11:36:56

Hello,

Super tuto, cela fait longtemps que je cherche un tuto simple, clair et trés complet sur les "RegExp".

Merci pour ton super travail Cacophrene.

Amicalement,

Little_Dev

signaler à un administrateur
Commentaire de lioneltina le 02/08/2007 16:48:25

Très gros travail, et pédagogie excellente.
Comme Little_Dev je cherche un tutorial de ce genre depuis longtemps, et il m'a déjà dépanné dans bien des situations. Un grand merci !
Sans remettre en cause donc la qualité excellente de ce travail, et malgré pas mal de temps passé à le lire en long en large et en travers, je n'arrive pas à créer une expression régulière dont l'énoncé n'a pas l'air si complexe que ça :
Toute expression qui commence par une chaine de caractère particulière (".modifier" dans mon cas) et qui finit par deux sauts de ligne successifs (\n\n).
J'ai essayé divers trucs, du genre "\.modifier.*\n\n", mais comme le . c'est tout sauf le saut de ligne... n'existe-t-il pas un caractère qui remplace tout ?
J'ai aussi essayé "\.modifier[.\n]*\n\n"... mais ça ne fonctionne pas.
Si quelqu'un qui n'est pas rebuté par la trivialité de la chose accepte de m'aider, ce serait super cool !!!

signaler à un administrateur
Commentaire de lioneltina le 03/08/2007 14:33:03

Bon, cette fois, j'ai vraiment trouvé.
J'ai été aidé il est vrai... :-)
Avec ceci, ça fonctionne (au cas où ça peut servir à quelqu'un):
\.Modifier(.+\r\n)*
Désolé pour ces 4 commentaires à la suite :-(

@+

signaler à un administrateur
Commentaire de eagleleader le 04/08/2007 10:24:10

Bonjour,

Apparemment, ce tuto est très bien fait mais je ne peux le lire car il apparaît chez moi ligne après ligne :



Les expressions rationnelles ("régulières")   Qu'est-ce qu'une expression rationnelle ? Tous les programmeurs disent du bien des expressions rationnelles. Pourtant, l'unanimité est assez rare dans le domaine. En fait, il y a une raison très simple à cela : elles sont à la fois maniables et performantes. Il serait donc dommage de s'en priver... Ce tutoriel vous propose donc d'aller y faire un petit tour. D'avance, je tiens à préciser que toutes les remarques, critiques, corrections et suggestions relatives à ce tutoriel sont les bienvenues. Je vous prie aussi de m'excuser pour les incohérences de mise en forme que vous pourriez rencontrer. On entend presque toujours parler d'expressions régulières (ou de regexp, par contraction de l'anglais regular expressions). Pourtant, l'expression "expressions régulières" est un calque de l'anglais "regular expressions" : ce n'est pas une traduction correcte. On devrait plutôt parler d'expressions rationnelles. En maths, on parle d'ailleurs bien d'expressions rationnelles. En maths ? Hé oui ! Il n'y a pas d'erreur, vous avez bien lu. Ces expressions sont associées à des maths, même si ça ne se voit pas au premier coup d'oeil (pour en savoir plus, il faut aller chercher du côté de la théorie des automates et des langages formels). Mais rassurez-vous, je ne vais pas vous parler d'automates, même si c'est intéressant, et nous ne ferons pas de mathématiques !   Comment y accéder à partir de Visual Basic ? Maintenant que les présentations sont faites, parlons un peu des expressions rationnelles avec Visual Basic. Pour les utiliser, cliquez sur le menu "Projet", puis sur l'onglet "Références". Dans la longue liste qui apparaît alors, cochez la ligne "Microsoft VBScript Regular Expressions 5.5". Voilà, c'est déjà terminé, vous pouvez vous en servir ! Certes oui... mais comment, me direz-vous ? C'est ce que nous allons apprendre maintenant... Attention ! Pour tirer le meilleur parti de ce tutoriel, il faut que vous puissiez essayer vous-même les exemples que je vous propose. C'est la raison pour laquelle je vous conseille de vous servir du RegExp Workshop de Renfield : http://www.codes-sources.com/code.aspx?ID=17331.



N'y a-t-il pas un problème sur le serveur concernant la mise en forme ?
Si quelqu'un aurait ce tuto mis en forme, pourrait-on me le communiquer ?

Cordialement,

signaler à un administrateur
Commentaire de Renfield le 03/10/2007 11:01:34 administrateur CS

effectivement, la mise en forme semble avoir sauté :S

signaler à un administrateur
Commentaire de Cacophrene le 09/11/2007 07:50:06

Bonjour à tous !

Navré pour cette longue absence... je viens seulement de revenir sur VBFrance et je constate avec stupéfaction que la mise en forme de mon tutoriel a sauté. Il va donc falloir que je la remette. J'en profiterai pour faire quelques corrections si besoin l'est. Encore navré pour le retard...

Cordialement,
Cacophrène

signaler à un administrateur
Commentaire de tototh le 14/02/2008 11:35:46

Note 9,999/10 car le tuto parfait n'existe jamais ;-)
Très, très bien fait : Clair concis et précis.
Que du bonheur. Et comme tu dit, je ne regarde plus du même ½il la famille des trim()
Et encore merci.

signaler à un administrateur
Commentaire de azizar02 le 04/03/2008 12:54:59

bonjour tout le monde

je cherche à développer une regEx pour valider l'heure saisie. Elle doit être de cette forme hhHmm avec biensur 00=<hh<24 et 00<=mm<59.
je crois pas que ce tuto est suffisant.

Merci.

signaler à un administrateur
Commentaire de Renfield le 04/03/2008 13:03:43 administrateur CS

pas besoin de RegExp pour si peu...

? isdate("29:40")
Faux

? isdate("20:40")
Vrai

signaler à un administrateur
Commentaire de Little_Dev le 04/03/2008 13:07:23

Hello

Effectivment pas besoin, mais si tu veux vraiment une RegExp : (2[0-4]|[0-1][0-9]):[0-5][0-9]
De tete il me semle que c'est bon.... mais a tester quand meme

Amicalement

@+

signaler à un administrateur
Commentaire de Cacophrene le 04/03/2008 14:14:05

Salut !

@Azizar02 :

Le tuto n'est pas suffisant pour quoi ? Si tu dis ça parce que l'on n'y trouve pas le cas qui t'intéresse, alors je suis au regret de te dire que tous les tutos que tu trouveras seront toujours incomplets... parce que les expressions rationnelles peuvent être utilisées dans des situations très différentes les unes des autres,et que l'on serait bien dans l'embarras s'il fallait en faire le tour...

De plus, il suffisait de lire un peu ce qui est écrit ici pour trouver une solution simple à ton problème à base de [...-...] comme l'a indiqué Little_Dev.

Sans parler du fait que cette utilisation revient à enfoncer une porte avec un lance-missiles.

Cordialement,
Cacophrène

signaler à un administrateur
Commentaire de azizar02 le 05/03/2008 16:33:29

Effectivement, vous avez tous raison.
Merci pour l'aide.

signaler à un administrateur
Commentaire de tchouny le 28/05/2008 18:45:44

Salut,
j'ai un petit prob. J'utilise VB 2005 et RegExp n'est pas reconnu même en ajoutant la référence mentionnée dans le tuto et en ajoutant un imports system.text.regularexpressions.
Regex oui mais ne contient pas .global ou .multiligne....
Quelqu'un pêut m'aider?
Thx

signaler à un administrateur
Commentaire de Renfield le 29/05/2008 07:28:35 administrateur CS

encore une question qui trouve tout bêtement réponse dans la doc MSDN:

le parametre multiline se spécifie dans le parametre Options de la méthode Match...
également dans le constructeur de RegEx et dans quelques autres du genre...

http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regexoptions.aspx

Pour le parametre Global, a toi d'appeler Match ou Matches


signaler à un administrateur
Commentaire de saradion le 08/06/2008 00:32:44

Merci beaucoup pour le tuto

beau travail

Cordialement

sara

Ajouter un commentaire



Nos sponsors

Sondage...

CalendriCode

Décembre 2008
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,390 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.