Tutoriel - Expression Régulière

Voici un petit guide pour démêler les apparents mystères de la fonction StringRegExp().

StringRegExp( "test", "pattern" [, flag ] )

"test" = la chaîne dans laquelle on recherche la correspondance..
"pattern" = Ou aussi nommer Motif ou encore Modèle et une chaîne composée de certains caractères qui permettent à la fonction de savoir précisément ce que vous souhaitez retrouver. Pas de If(s), And(s), ou autre.. Ca correspond ou ca ne correspond pas.
flag[optionel] = Indicateur (drapeau) qui dit à la fonction si vous voulez seulement savoir si le "pattern" à été trouvé, ou si vous voulez qu'elle vous retourne le premier élément trouvé, ou si vous voulez qu'elle vous retourne tous les éléments dans la chaîne "test".

Principes Fondamentaux

Comme vous l'avez constaté,la chaîne "pattern" est la seul partie compliquée de la fonction StringRegExp() (Surnommer : SRE). Je crois qu'il est mieux de penser au Pattern comme un élément qui dit à la fonction de faire la correspondances caractère par caractère. Il existe différentes méthodes pour trouver un caratère : Si vous voulez contrôler la chaîne "test", cela sera assez simple. Si vous voulez que la fonction SRE cherche en premier un "t" dans la chaîne. Si il en trouve un, alors il supposera avoir trouvé la correspondance, et le reste du pattern est utilisé pour essayer de prouver que ce qu'il à trouvé n'est pas une correspondance. Donc, si le caractère suivant est un "e", cela pourrait rester une correspondance. Admettons que la lettre suivante soit un "x". SRE sait immediatement qu'il n'y à pas de correspondance puisque le troisième caractère de la chaîne est un "s".
 

Exemple 1 :

MsgBox(0, "SRE Exemple 1. Résultat = ", StringRegExp("text", 'test'))

Dans cet exemple, la boite de message devrait lire "0", ce qui signifie que le pattern "test" n'a pas été trouvé dans la chaîne "text". Je sais que cela peut vous paraître simpliste, mais au moins vous comprenez pourquoi il n'a pas été trouvé.

Une autre méthode de spécifier un pattern est en utilisant une paire de de crochet ("[ ... ]"). Vous pouvez comparer la paire de crochet, à la fonction logique "OR". Utilisons l'exemple précédent. Nous voulons trouver l'une ou l'autre des chaînes suivantes "test" ou "text". Ainsi, la méthode pour trouver le pattern est de pensser comme la fonction SRE :
Le premier caractère à comparer est le "t", ensuite la lettre "e", et ainsi de suite. Maintenant, nous voulons comparer un "s" OU un "x", donc nous allons utiliser les crochets comme substitut : "[sx]" veut comparer un "s" ou un "x". Et enfin, la dernière lettre est de nouveau un "t".

Example 2

MsgBox(0, "SRE Exemple 2. Résultat = ", StringRegExp("text", 'te[sx]t'))
MsgBox(0, "SRE Exemple 2. Résultat = ", StringRegExp("test", 'te[sx]t'))

Dans les deux cas, nous aurons le résultat "1", puisque le pattern correspond aux chaînes "test" et "text".

Vous pouvez aussi spécifier combien de fois vous voulez la corespondance de chaques caractères en utilisant "{nombre de correspondance}" ou vous pouvez spécifier une plage en utilisant "{min, max}". Le premier exemple ci-dessous est redondant, mais il vous montre ce que je veux dire :

Exemple 3

MsgBox(0, "SRE Exemple 3. Résultat = ", StringRegExp("text", 't{1}e{1}[sx]{1}t{1}'))
MsgBox(0, "SRE Example 3. Résultat = ", StringRegExp("aaaabbbbcccc", 'b{4}'))



Principes Fondamentaux (Avancés)

Tout de suite vous penserez, "n'est-ce pas une fonction StringInStr() améliorée ? ". Bien, en utilisant un "flag" à 0, la plupart du temps vous avez raison. Mais SRE est beaucoup plus puissant que cela. Comme vous utiliserez SRE de plus en plus, Vous constaterez que vous en connaissez de moins en mois sur le type de pattern que vous cherchez. Il y à des manières d'être de moins en moins spécifique sur chaque caractères que vous voulez spécifier dans le pattern. Prenez par exemple une ligne d'un log de Chat d'un jeu :" Gnarly le Monstre vous frappe pour 18 dégâts." Vous voulez trouver combien de domage Gnarly le Monstre vous à infligé. Hé bien, vous ne pouvez utiliser StringInStr() parce que vous ne cherchez pas "18", mais plutôt "????", où ? peut être n'importe quel chiffre.

Voici comment j'assemblerais ce pattern. Regardez ce que vous faites et ne connaissez pas ce que vous voulez trouver :
1) Vous savez qu'il contiendra TOUJOURS rien que des chiffres.
2) Vous savez qu'il ce sera PARFOIS d'une longueur de 2 caractères.
2a) Vous savez que le maximum de dommage qu'un monstre peut faire est de 999.
2b) Vous savez que le minimum de dommage qu'un monstre peut faire est de 0.
3) Vous savez qu'il sera TOUJOURS d'une longueur entre 1 et 3 caractères.
4) Vous savez qu'il n'y a aucun autre chiffre dans la chaîne de test.

À ce point, je voudrais présenter la valeur "1" du FLAG et les caractères de groupement "()". La valeur "1" du flag signifie que SRE controlera non seulement votre pattern, mais retournera aussi un tableau, avec chaque élément du tableau constituant un "groupe" de caractères capturés . Ainsi sans trop s'éloigner du chemin, prenez cet exemple :

Exemple 4

$asResult = StringRegExp("Voici un test d'exemple", '(test)', 1)
If @error == 0 Then
    MsgBox(0, "SRE Exemple 4. Résultat = ", $asResult[0])
EndIf
$asResult = StringRegExp("Voici un test d'exemple", '(te)(est)', 1)
If @error == 0 Then
    MsgBox(0, "SRE Exemple 4. Résultat = ", $asResult[0] & "," & $asResult[1])
EndIf

 

Donc, pour commencer le pattern doit correspondre quelque part dans la chaîne d'essai. Si c'est bon, on dit à SRE de "capturer" n'importe quels groupes ("()") et les stocker dans un tableau de retour. Vous pouvez utiliser des captures multiples, comme démontré par la deuxième partie de code dans l'Exemple 4.

Ok, revenons au Monstre Gnarly. Maintenant que nous savons comment capturer du texte, construisons notre modèle : Puisque vous savez que vous cherchez des chiffres, il y a 3 façons de spécifier la "correspondance de n'importe quel chiffre" : "[:digit:]", "[0-9]", et "\d". Le premier est probablement le plus facile a comprendre. Il y a quelques classes (digit, alnum, space, etc. Vérifiez le fichier d'aide pour une liste complète) Vous pouvez utiliser pour spécifier des jeux de caractères, l'un d'entre eux étant le chiffre. "[0-9]" Spécifie simplement une plage de chiffres de 0 à 9. "\d" Est juste un caractère spécial qui signifie la même chose que précédement. Il n'y a aucune différence entre les trois solutions, Et avec toutes les SRE il y a plusieurs façons de construire n'importe quel pattern.

Donc, pour commencer nous savons que nous voulons capturer des chiffres, indiquez le avec des parenthèses ouvrantes "(". Ensuite, nous savons que nous voulons capturer entre 1 et 3 caractères, tous étant des chiffres, donc notre pattern ressemble maintenant à ceci : "([0-9]{1,3}". Et finalement fermez le avec la parenthèse fermante pour indiquer la fin de notre groupe: "([0-9]{1,3})". Essayons le :

Example 5

$asResult = StringRegExp("Gnarly le Monstre vous frappe pour 18 dégâts.", _
            '([0-9]{1,3})', 1)
If @error == 0 Then
    MsgBox(0, "SRE Exemple 5. Résultat = ", $asResult[0])
EndIf

 

Là c'est bon, la boîte de dialogue montre correctement "18".

Ensuite nous devons comprendre les exclusions de groupes. La manière d'indiquez ces groupes est d'ouvrir le groupe avec "(?:" au lieu de n'utiliser que "(". Admettons que votre log dit "Vous détourné 36 des 279 dégâts du Monstre Gnarly." Maintenant si vous y exécutez l'exemple SRE 5, vous aurez "36" au lieu de "279". Dans ce cas, ce que je devrais faire c'est de déterminer ce qui est différent entre les nombres. Ce qui me saute aux yeux c'est que le deuxième nombre est toujours suivi par un espace puis par le mot "dégâts". Nous pourrions juste modifier notre pattern précédent comme ceci : "([0-9]{1,3} dégâts)", mais si notre script cherche simplement la quantité de dégât, sans le mot "dégâts" planté à la fin du nombre ? C'est là que vous aurez besoin d'utiliser les exclusions de groupes.

Exemple 6

$asResult = StringRegExp("Vous détourné 36 des 279 dégâts du Monstre Gnarly.", '([0-9]{1,3})(?: dégâts)', 1)
If @error == 0 Then
    MsgBox(0, "SRE Exemple 6. Résultat = ", $asResult[0])
EndIf

 

Cela pourrait devenir très long, mais j'ai surtout voulu montrer les fondements du fonctionnement des expressions régulières et surtout comment SRE "pense". Quelques petites choses à garder en tête :
- Souvenez-vous de réfléchir au pattern caractère par caractère
- La fonction StringRegExp() trouve le premier caractère dans le pattern, alors c'est à vous de fournir suffisement d'évidence pour "prouver" si en effet il y à correspondance. L'exemple 6 est une bonne démonstration de ceci.
- Rappelé vous [ ... ] signifie OU ([xyz] correspond à un "x", un "y", OU un "z")
Si vous avez d'autre questions, consultez en premier le fichier d'aide ! Il explique en détail tous les éléments importants de la syntaxe des SRE(s). Une chose à regarder en particulier, c'est la section sur les "Caractères à Répétition". Cela peut rendre votre pattern plus lisible en substituant certains caractères par des portées de caractères. Par exemple : "*" est équivalant à {0,} Ou la plage de 0 à n'importe quel nombre de caractères.

Bonne chance, Les expressions Régulières peuvent grandement diminuer la longueur de votre code, et le rendre plus simple à modifier ultérieurement. Les corrections et les rétroactions (feedback) sont bienvenus !

Resources Anglaise

Article Wikipedia - Regular Expressions - Merci blindwig.

The 30 Minute Regex Tutorial - by Jim Hollenhorst.


GUI pour tester divers pattern StringRegExp() - Merci steve8tch. Credit: w0uter



Resources Française

Article Wikipedia - Expression rationnelle.

Les expressions régulières PCRE de PHP.

Les Expressions Rationnelles appliquées en VBA Access.

 

 

 

Merci à neogia pour ce tutoriel.