NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020
-
13 déc. 2017 à 21:39
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023
-
18 déc. 2017 à 13:44
Bonjour,
Je bute sur la récupération des Submatches des (groups) de mon pattern.
J’espère que ce que j’essaie de faire est réalisable?
Pouvez-vous m’aider?
TxtSource = "\\\*-****/Un test, Pourquoi faire? c'est fou ça! \****-*///" ReslutSpeciChars = ""
Dim strText, RegularExpressioN
'([^\,]|^)([\,])(?![\,]) '[^\,] = n'est pas une virgule. '| = ou. '^ = est au début de la chaîne. '(?![\,]) = n'est pas suivit d'une virgule. 'Equivalent a (?<![\,])[\,](?![\,]) soit (pas de virgule avant, pas de virgule après), mais non supporter par vb (test arrière (?<!....).
jordane45
Messages postés37519Date d'inscriptionmercredi 22 octobre 2003StatutModérateurDernière intervention 2 juin 2023341 13 déc. 2017 à 22:40
Bonjour,
Ton pattern ne semble pas bon.
Commence par le tester en ligne, par exemple ici : http://regexstorm.net/tester Sinon.. décris nous exactement ce que tu espères obtenir.
Prenons l’exemple avec le caractère ",".
Normalement j’aurais du utiliser ce pattern : (?<![\,])[\,](?![\,]) soit (pas de virgule avant, pas de virgule après).
Vu que le langage VBScript ne supporte pas les tests arrière (?<!…), il a fallu ruser, en décrivant et en consommant la position avant le caractère ciblé: ([^\,]|^)([\,])(?![\,]) (cette position peut être soit le début de la chaîne ^, soit un caractère qui n'est pas une virgule [^\,]). Ce qui change, c'est que deux caractères sont consommés par la pattern (le caractère précédent et le caractère cible).
Pour le remplacement, il est nécessaire de mettre une référence au groupe de capture dans la chaîne de remplacement pour restituer le caractère qui précède le caractère cible.
Le code fonctionne bien avec mon première caractère "\" soit le pattern: ([^\\]|^)([\\])(?![\\]) mais des que je veux traiter les deux autres !!!(groupes séparés par "|").
Je bute sur la manière d’adapter mes matches pour le value et la position de mes caractères.
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 Modifié le 14 déc. 2017 à 00:11
Voici le test qui fonctionne :
Référence au groupe de capture "$1".
"$&" est sensé reprendre tous les groupes de capture pour la suite.
TxtSource = "\\\*-****/Un test, Pourquoi faire? c'est fou ça! \****-*///" ReslutSpeciChars = ""
Dim strText, RegularExpressioN
'([^\,]|^)([\,])(?![\,]) '[^\,] = n'est pas une virgule. '| = ou. '^ = est au début de la chaîne. '(?![\,]) = n'est pas suivit d'une virgule. 'Equivalent a (?<![\,])[\,](?![\,]) soit (pas de virgule avant, pas de virgule après), mais non supporter par vb (test arrière (?<!....).
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624 14 déc. 2017 à 00:14
C’est pas clair, j’ai mis ton code « qui marche » dans regexstorm, et ça capture un anti slash coincé entre un espace et une étoile. C’est pas ce que j’appellerais isolé.
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 Modifié le 14 déc. 2017 à 00:40
Attention j'ai corrigé mon exemple qui fonctionne sûrement entre temps. ds le replace j'ai remplacé "$1" par "$&"
Quand je dis isolé c'est isolé d'un groupe de caractères identiques.
Le résultat du MsgBox est :
1 correspondance(s) trouvé(s).
Correspondance trouvée "\" en position: 49
Ce qui est exacte.
As tu vu l'explication poste 2?
match.Submatches(1) me supprime l’espace avant le caractère et me le retourne.
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624 14 déc. 2017 à 07:14
Avant de supprimer et de remplacer,n je voudrais comprendre ce que tu cherches à capturer.
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 14 déc. 2017 à 09:57
Dans l'exemple du poste n°3 je recherche la ou les occurrences "\" qui ne font pas partie d'un groupe "\\\".
Pour le pattern utilisé voir explication du poste n°2.
Explication supplémentaire:
Caractères spéciaux
(\#) Correspond au caractère (#) suivant le backslash (exceptés les caractères a-z et 0-9).
Par exemple, la séquence "\\" signifie "\" , "\." correspond au caractère "." (stop), "\$" correspond à "$".
jordane45
Messages postés37519Date d'inscriptionmercredi 22 octobre 2003StatutModérateurDernière intervention 2 juin 2023341
>
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 14 déc. 2017 à 10:32
Bonjour,
Whismeril ne te demande pas de lui expliquer comment fonctionne une regex ni ce que sont les pattern que tu utilises...
Il veut (et il n'est pas le seul...) savoir ce que tu souhaites EXACTEMENT obtenir en partant de ta phrase d'exemple de ton premier message......
En gros...
TxtSource = "\\\*-****/Un test, Pourquoi faire? c'est fou ça! \****-*///"
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624
>
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 14 déc. 2017 à 12:06
Comme le dit Jordane, je sais me servir des regex, c’est même un jeu que j’apprécie. Cependant dans ton cas, je n’arrive pas à faire le lien entre ce que tu expliques et les patterns que tu montres.
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 14 déc. 2017 à 12:13
Le résultat du remplacement attendu n'est pas visible vu que je remplace le caractère par lui-même.
J'ai besoin de ce remplacement pour la suite de mon programme.
Pour voir ce qui est trouvé ajouter des parenthèses autour du $& soit ($&) ce qui donne au replace pour les caractères "\","/" et "*".
TxtSource = \\(\*)-***(*/)Un test, Pourquoi faire? c'est fou ça!( \)****(-*)///
Jusque-là pas de problème le remplacement est bon.
C'est au niveau de la récupération de la valeur et de la position de de mes caractères que ça coince
En utilisant le pattern: ([^\\]|^)([\\])(?![\\]) pour le caractères "\" c'est bon le résultat du MsgBox est:
1 correspondance(s) trouvé(s).
Correspondance trouvée "\" en position: 49
Mais, dès que j'essaie un pattern avec les caractères "\"|"/"|"*".
([^\\]|^)([\\])(?![\\])|([^\/]|^)([\/])(?![\/])|([^\*]|^)([\*])(?![\*])
Le résultat est :
4 correspondance(s) trouvé(s).
Correspondance trouvée "" en position: 2
Correspondance trouvée "" en position: 8
Correspondance trouvée "\" en position: 49
Correspondance trouvée "" en position:54
J'aimerais avoir ceci:
4 correspondance(s) trouvé(s).
Correspondance trouvée "*" en position: 3
Correspondance trouvée "/" en position: 9
Correspondance trouvée "\" en position: 49
Correspondance trouvée "*" en position:55
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624 14 déc. 2017 à 12:36
4 correspondance(s) trouvé(s).
Correspondance trouvée "*" en position: 3
Correspondance trouvée "/" en position: 9
Correspondance trouvée "\" en position: 49
Correspondance trouvée "*" en position:55
Voilà c’est tout ce qui m’intéresse. Je tache d’y regarder cet après-midi
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 14 déc. 2017 à 12:55
Désolé je n'avais pas compris t'as demande ! Sympa de te pencher sur mon problème.
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624 14 déc. 2017 à 14:02
VBS accepte les groupes avec des noms?
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624 14 déc. 2017 à 14:21
En pariant que oui, regarde ce lien (non cliquable à cause d'un vieux bug du site)
Error: Erreur de syntaxe dans l'expression régulière
Code: 800A1399
Source: Erreur d'exècution Microsoft VBScript
System: La ressource de cluster n'a pas pu êtrz créée dans le moniteur de resources spécifié.
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 Modifié le 14 déc. 2017 à 22:33
Sous vbs le résultat est identique au donnée de l’onglet Context de regexstorm:
\\\|-****|Un test, Pourquoi faire? c'est fou ça! |****-|///
Hâte de voir comment tu va traiter la suite, encore merci !
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624 14 déc. 2017 à 22:35
Quelle suite?
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 Modifié le 14 déc. 2017 à 23:16
J'aimerais avoir ceci:
4 correspondance(s) trouvé(s).
Correspondance trouvée "*" en position: 3
Correspondance trouvée "/" en position: 9
Correspondance trouvée "\" en position: 49
Correspondance trouvée "*" en position:55
poste N°13
Au final sur le remplacement, ton pattern fait la même chose que le mien sauf que si la chaîne commence par un des caractères défini est qu’il ne fait pas partie d’un groupe de caractères identique, ça ne fonctionne pas et il ne reprend pas le caractère d’origine.
j’en reviens a l’idée de départ, qui me fait penser que mon problème n’est pas un problème de pattern, mais bien un problème de traitement sous vbs !
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624 15 déc. 2017 à 07:34
4 correspondance(s) trouvé(s).
Correspondance trouvée "*" en position: 3
Correspondance trouvée "/" en position: 9
Correspondance trouvée "\" en position: 49
Correspondance trouvée "*" en position:55
ça c’est en VBS que tu dois l’fficher. Et je ne connais pas VBS.
Par contre, comme tu peux le voir sur regexstorm, la capture n’est pas toujours au même index, il faut donc dans ta boucle foreach tester quelle est la capture valide et afficher les données associées.
Au final sur le remplacement, ton pattern fait la même chose que le mien sauf que si la chaîne commence par un des caractères défini est qu’il ne fait pas partie d’un groupe de caractères identique, ça ne fonctionne pas et il ne reprend pas le caractère d’origine.
Peux donner un morceau de texte qui ne marche pas?
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 Modifié le 15 déc. 2017 à 09:38
Pour l'exemple j'ai ajouté "\-" devant le texte.
\-\\\*-****/Un test, Pourquoi faire? c'est fou ça! \****-*///
Mon souci est, je pense aussi au niveau de la manière de récupérer les infos des groupes de capture.
"La boucle For Each" je ne sais pas trop comment la gérer.
C'est pour cela que j'ai posté sur le forum VBScript et non sur RegExp.
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624 15 déc. 2017 à 10:33
Alors pour le \- c’est bien un problème de pattern, je n’ai pas géré le debut de texte (ni la fin d’ailleurs).
Et donc avant de regler le soucis de boucle réglons, les regex.
Est ce que tu veux capturer le - aussi?
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 15 déc. 2017 à 17:00
Voici la solution retenue en grand merci Whismeril
Sub Macro1()
Dim pattern As String Dim texte As String pattern = "([^\\]|^)([\\])(?![\\])|([^\/]|^)([\/])(?![\/])|([^\*]|^)([\*])(?![\*])|([^\-]|^)([\-])(?![\-])" texte = "\-\\\*-****/Un test, Pourquoi faire? c'est fou ça! \****-*///*/"
Dim regex As VBScript_RegExp_55.RegExp Set regex = New VBScript_RegExp_55.RegExp regex.pattern = pattern regex.Global = True
Dim match As VBScript_RegExp_55.match Dim matches As VBScript_RegExp_55.MatchCollection Set matches = regex.Execute(texte) Debug.Print matches.Count
Dim sortie As String For Each match In matches For i = 1 To match.SubMatches.Count - 1 Step 2 If Not (match.SubMatches(i) = "") Then Debug.Print ("Correspondance trouvée """ & match.Submatches(i) & """ en position: " & match.FirstIndex + Len(match.Value) - 1) End If Next i Next match
End Sub
Je rencontre un nouveau problème!
Si deux caractères "seule" et côte à côte seule le 1er et prit en compte
/**** *\\/ Ok pour le 0 le 6 et le 9
/**** *\ Ok pour le 0 et le 6 mais pas le 7
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624 15 déc. 2017 à 18:18
Là, je ne suis pas sûr, mais il me semble que c'est une limitation des regex: 2 captures ne se chevauchent pas.
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624 15 déc. 2017 à 18:23
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 Modifié le 15 déc. 2017 à 23:53
Je dois dans la mesure du possible rester sous VBScript. Penses tu qu’il soit possible de traiter chaque "sous patterns" indépendamment ?
Dans une sorte de boucle et surtout récupérer chaque positions et valeurs?
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624 16 déc. 2017 à 00:03
NeriXs
Messages postés116Date d'inscriptionlundi 4 mai 2015StatutMembreDernière intervention18 août 2020 16 déc. 2017 à 14:13
N’étant pas très a mon aise, avec la gestion d’une boucle dans ce contexte de multiple sous pattern,
j’appréciais beaucoup qu’une personne expérimentée puisse me donner un exemple complet.
Whismeril
Messages postés18416Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 1 juin 2023624 16 déc. 2017 à 21:32
Ceci marche sous VBA
Sub Macro1()
Dim texte As String
texte = "\-\\\*-****/Un test, Pourquoi faire? c'est fou ça! \****-*///*/"
For Each Caractere In Array("\\", "\*", "-")
Recherche Caractere, texte
Next
End Sub
Sub Recherche(ByVal Caractere As String, texte As String)
Dim Pattern As String
Pattern = "([^" & Caractere & "]|^)(" & Caractere & ")(?!" & Caractere & ")" 'on fait un pattern
Dim regex As VBScript_RegExp_55.RegExp
Set regex = New VBScript_RegExp_55.RegExp
regex.Pattern = Pattern
regex.Global = True
Dim match As VBScript_RegExp_55.match
Dim matches As VBScript_RegExp_55.MatchCollection
Set matches = regex.Execute(texte)
Debug.Print "Le pattern " & Pattern & " retourne " & matches.Count; " captures"
Dim sortie As String
For Each match In matches
For i = 1 To match.Submatches.Count - 1 Step 2
If Not (match.Submatches(i) = "") Then
Debug.Print ("Correspondance trouvée """ & match.Submatches(i) & """ en position: " & match.FirstIndex + Len(match.Value))
End If
Next i
Next match
End Sub