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 ça ne correspond pas.
flag [optionnel] = 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".
Comme vous l'avez constaté,la chaîne "pattern" est la seule partie compliquée de la fonction StringRegExp() (Surnommée : SRE). Je crois qu'il est mieux de penser au Pattern comme un élément qui dit à la fonction de faire la correspondance caractère par caractère. Il existe différentes méthodes pour trouver un caratère : si vous voulez chercher la chaîne "test", cela sera assez simple. Vous voulez dire à la fonction SRE de chercher en premier un "t" dans la chaîne. Si elle en trouve un, alors elle supposera avoir trouvé une correspondance, et le reste du pattern est utilisé pour essayer de prouver que ce qu'elle a trouvé n'est pas une correspondance. Donc, si le caractère suivant est un "e", cela pourrait confirmer une correspondance. Supposons que la lettre suivante soit un "x". SRE sait immédiatement qu'elle n'a pas trouvé de correspondance puisque le troisième caractère de la chaîne que vous lui avez dit de regarder est un "s".
Exemple 1 :
MsgBox(0, "SRE Exemple 1 Result", 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 pour spécifier un pattern consiste à utiliser une paire de de crochet ("[ ... ]"). Vous pouvez considérer que l'ensemble est comparable à 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 penser comme la fonction SRE penserait: Le premier caractère à comparer est le "t", ensuite la lettre "e", et ainsi de suite. Maintenant, nous voulons trouver un "s" OU un "x", donc nous allons utiliser les crochets comme substitut : "[sx]" ce qui signifie trouver un "s" ou un "x". Et enfin, la dernière lettre est de nouveau un "t".
Exemple 2
MsgBox(0, "SRE Example 2 Result", StringRegExp("text", 'te[sx]t'))
MsgBox(0, "SRE Example 2 Result", 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 correspondance de chaque caractère 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 Example 3 Result", StringRegExp("text", 't{1}e{1}[sx]{1}t{1}'))
MsgBox(0, "SRE Example 3 Result", StringRegExp("aaaabbbbcccc", 'b{4}'))
Tout de suite vous penserez probablement, "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 puissante que cela. En utilisant SRE de plus en plus souvent, vous constaterez que vous en connaissez de moins en mois sur le type de pattern que vous cherchez. Il y a 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 fichier log d'inventaire: "Il restait 18 feuilles dans la rame de papier." Vous voulez trouver le nombre de feuilles restantes. 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 qu'une rame pleine contient 500 feuilles.
2b) Vous savez que le minimum de feuille est 0.
3) Vous savez que le nombre de feuilles sera TOUJOURS 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, considérez cet exemple :
Exemple 4
$asResult = StringRegExp("This is a test example", '(test)', 1)
If @error == 0 Then
MsgBox(0, "SRE Example 4 Result", $asResult[0])
EndIf
$asResult = StringRegExp("This is a test example", '(te)(st)', 1)
If @error == 0 Then
MsgBox(0, "SRE Example 4 Result", $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 du code de l'Exemple 4.
Ok, revenons au fichier log. 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". La première est probablement la 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 spécifier des jeux de caractères, l'un d'entre eux étant les chiffres. "[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("Il y avait 18 feuilles restantes dans la rame de papier.", _
'([0-9]{1,3})', 1)
If @error == 0 Then
MsgBox(0, "SRE Example 5 Result", $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 fichier log dit "Vous avez utilisé 36 des 279 pages." Maintenant si vous y exécutez la fonction SRE de l'exemple 5 la dessus, 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 "pages". Nous pourrions juste modifier notre pattern précédent comme ceci : "([0-9]{1,3} pages)", mais si notre script cherche simplement la quantité de pages, sans le mot "pages" planté à la fin du nombre ? C'est là que vous aurez besoin d'utiliser les exclusions de groupes.
Exemple 6
$asResult = StringRegExp("You used 36 of 279 pages.", '([0-9]{1,3})(?: pages)', 1)
If @error == 0 Then
MsgBox(0, "SRE Example 6 Result", $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, puis c'est à vous de fournir suffisamment d'évidence pour "prouver" si la correspondance est trouvé ou pas. 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 plages. 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 retours sont bienvenus !
Wikipedia Article - Regular Expressions - Thanks blindwig.
The 30 Minute Regex Tutorial - by Jim Hollenhorst.
GUI for testing various StringRegExp() patterns - Thanks steve8tch. Credit: w0uter
Thanks to neogia for this tutorial.