IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VBScript Discussion :

RegExp récupérer Submatches ?


Sujet :

VBScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut RegExp récupérer Submatches ?
    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?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    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 (?<!....).
     
    '"\" =([^\\]|^)([\\])(?![\\])
    '"/" =([^\/]|^)([\/])(?![\/])
    '"*" =([^\*]|^)([\*])(?![\*])
     
    FindSpeciChars = "([^\\]|^)([\\])(?![\\])"_
    	       & "|([^\/]|^)([\/])(?![\/])"_
    	       & "|([^\*]|^)([\*])(?![\*])"
     
    	strText = TxtSource		
    	Set RegularExpressioN = New RegExp
    	RegularExpressioN.Pattern = FindSpeciChars
    	RegularExpressioN.Global = True
    	Set Matches = RegularExpressioN.Execute(strText)
    		If Matches.Count > 0 Then		  
    		    MatchMsg = Matches.Count & " correspondance(s) trouvée(s)." & vbCRLF
    		    	For Each Match In Matches
    		      		MatchMsg = MatchMsg & "Correspondance trouvée """ & match.Submatches(1) & """ en position: " & match.FirstIndex + Len(match.SubMatches(0)) & vbCrLf
    		    	Next
    		    'MsgBox MatchMsg
    		Else
    		    MsgBox "Aucun match", 0, "VBScript RegExp Tester"
    		End If		  										
    	strText = RegularExpressioN.Replace(strText, "$&")'"$1" "$&"
    	Set RegularExpressioN = Nothing
    	ReslutSpeciChars = strText
     
    MsgBox TxtSource & vbCrLf & ReslutSpeciChars & vbCrLf & MatchMsg

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Bon je parviens à remplacer est à récupérer\positionner les bonnes valeurs des caractères spéciaux qui ne font pas partie d'un groupe de caractères identiques "isolé".
    Je rencontre un autre problème si deux caractères isolés sont côte à côte, seule le 1er est pris en compte.
    Ça se complique grave.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    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 (?<!....).
     
    '(\?)|(\!)|(\:)|(\;)|(\,)|(\')|(\&)|(\~)|(\{)|(\})|(\()|(\))|(\[)|(\])|(\@)|(\^)|(\¨)|(\$)|(\£)|(\€)|(\.)|(\<)|(\>)|(\|)
     
    '"\" =([^\\]|^)([\\])(?![\\])		'"&" =([^\&]|^)([\&])(?![\&])		"£" =([^\£]|^)([\£])(?![\£])		
    '"/" =([^\/]|^)([\/])(?![\/])		'"~" =([^\~]|^)([\~])(?![\~])		"€" =([^\€]|^)([\€])(?![\€])		
    '"*" =([^\*]|^)([\*])(?![\*])		'"{" =([^\{]|^)([\{])(?![\{])		"." =([^\.]|^)([\.])(?![\.])		
    '"+" =([^\+]|^)([\+])(?![\+])		'"}" =([^\}]|^)([\}])(?![\}])		"<" =([^\<]|^)([\<])(?![\<])		
    '"-" =([^\-]|^)([\-])(?![\-])		'"(" =([^\(]|^)([\(])(?![\(])		">" =([^\>]|^)([\>])(?![\>])		
    '"=" =([^\=]|^)([\=])(?![\=])		'")" =([^\)]|^)([\)])(?![\)])		"|" =([^\|]|^)([\|])(?![\|])		
    '"?" =([^\?]|^)([\?])(?![\?])		'"[" =([^\[]|^)([\[])(?![\[])		
    '"!" =([^\!]|^)([\!])(?![\!])		'"]" =([^\]]|^)([\]])(?![\]])		
    '":" =([^\:]|^)([\:])(?![\:])		'"@" =([^\@]|^)([\@])(?![\@])		
    '";" =([^\;]|^)([\;])(?![\;])		'"^" =([^\^]|^)([\^])(?![\^])		
    '"," =([^\,]|^)([\,])(?![\,])		'"¨" =([^\¨]|^)([\¨])(?![\¨])		
    '"'" =([^\']|^)([\'])(?![\'])		'"$" =([^\$]|^)([\$])(?![\$])		
     
    '							Char		 |			char				|		char 
    FindSpeciChars = "([^\\]|^)([\\])(?![\\])|([^\/]|^)([\/])(?![\/])|([^\*]|^)([\*])(?![\*])" _
    			  & "|([^\-]|^)([\-])(?![\-])"
     
     strText = TxtSource  
     Set RegularExpressioN = New RegExp
     RegularExpressioN.Pattern = FindSpeciChars
     RegularExpressioN.Global = True
     Set Matches = RegularExpressioN.Execute(strText)
     	If Matches.Count > 0 Then    
    		MatchMsg = Matches.Count & " correspondance(s) trouvée(s)." & vbCRLF
    			For Each Match In Matches
    				For i = 1 To match.SubMatches.Count - 1 Step 2
    					If Not (match.SubMatches(i) = "") Then
                    		MatchMsg = MatchMsg & "Correspondance trouvée """ & match.Submatches(i) & """ en position: " & match.FirstIndex + Len(match.Value) - 1 & vbCrLf 
            		Next     
    			Next
          			'MsgBox MatchMsg
    			Else
          			MsgBox "Aucun match", 0, "VBScript RegExp Tester"
    	End If              
     strText = RegularExpressioN.Replace(strText, "($&)") 'Parenthèses pour aider à la localisation des caractères remplacés.
     Set RegularExpressioN = Nothing
     ReslutSpeciChars = strText
     
    MsgBox TxtSource & vbCrLf & ReslutSpeciChars & vbCrLf & MatchMsg

  3. #3
    Invité
    Invité(e)
    Par défaut
    Ce genre de pattern "([\\\*/-])(?<!\1\1)(?!\1)" solutionnerait mon problème, mais encore une fois le fameux test arrière non supporté pas VBScript.
    une alternative est elle possible*?

  4. #4
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    J’espère que ce que j’essaie de faire est réalisable?
    Tout le problème est là, personne ne serait capable de dire ce que tu cherches à faire. Ça serait une bonne chose d'expliquer où tu veux en venir. (Typiquement avec une chaîne en entrée et le résultat espéré en sortie).

    ...si deux caractères isolés sont côte à côte...
    S'il sont côte à côte, ils ne sont pas si isolé que ça. Là encore, on sombre dans les sables mouvants du pas très clair.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Le bute est pour chaque caractère spéciaux lors qu’ils ne font pas partie d’un groupe de caractères identiques la récupération de la valeur et de la position et le remplacement par lui-même.

    Quand je parle des caractères côte à côte c'est dans le cas ou ceux-ci ne sont pas identiques.

    Exemple dans la chaîne suivante: \\?\???
    Les caractères du pattern: \|?
    j’ai bien un \ isolé et un ? Isolé aussi, mais comme ils sont côte a côte seule le ? Est reconnue car pour le \ mon caractère précédent est déjà consommé, il a une sorte de chevauchement.
    Dernière modification par Invité ; 16/12/2017 à 00h32.

  6. #6
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    Mouais, on est pas plus renseigner sur la raison du remplacement d'un caractère par lui même.

    Toujours est-il que pour arriver à tes fins, tu peux consommer ce qui ne t'intéresse pas en le plaçant dans un groupe de capture pour pouvoir l'identifier en le faisant suivre d'un autre groupe de capture pour le caractère isolé. Mais attention, celui-ci devra être optionnel, car rien ne prouve que par exemple ** soit suivi d'un des caractères recherchés isolé.

    Donc j'utiliserai cette pattern:((?:([!$&-/:-@\[-^{-~£€¨])\2+)*)([!$&-/:-@\[-^{-~£€¨]?).

    En détail:
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    (    # groupe de capture 1: récupère les éventuels caractères répétés
        (?: # groupe non-capturant
            ([!$&-/:-@\[-^{-~£€¨]) # groupe de capture 2: capture un des caractères
            \2+            # uniquement quand celui-ci est répété
        )* # répète ce groupe zéro ou n fois de manière gourmande (greedy): c à d autant de fois que possible
    ) # ferme le groupe de capture 1
    ( # groupe de capture 3: qui contient soit le caractère isolé, soit rien
    [!$&-/:-@\[-^{-~£€¨]?
    )

    À noter que [!$&-/:-@\[-^{-~£€¨] est une classe de caractères contenant tous les caractères présents dans ton alternative de départ. Pour que ce soit plus court à écrire, il suffit d'utiliser des rangs de caractères comme &-/ (au même titre que a-z ou 0-9, voir la table iso-8859-1).

    Bien entendu, avec cette pattern tu devras modifier ton code:
    • Pour vérifier que le groupe 3 n'est pas vide avant d'afficher les résultats du match
    • Pour déterminer la position du groupe 3 en additionnant la position du groupe 1 à sa taille
    • Placer une référence au groupe 1 dans ta chaîne de remplacement


    NB: l'échappement devant [ dans une classe de caractère n'est peut-être pas utile (à tester).


    Si le fait que le groupe de capture 3 peut être éventuellement vide pose problème (pour par exemple placer des parenthèses autour du caractère), deux solutions sont envisageables:
    • Modifier la pattern pour qu'elle consomme tous les caractères de la chaîne sans exception et utiliser des groupes de capture pour savoir ce qui est le caractère isolé et ce qui ne l'est pas, puis ne pas utiliser la méthode replace et reconstruire la chaîne avec les différents matches.
    • Utiliser cette fonctionnalité de Javascript émulée pour vbs qui permet d'utiliser une fonction de rappel à la place d'une chaîne de remplacement: voir ici

Discussions similaires

  1. Réponses: 11
    Dernier message: 18/08/2015, 22h13
  2. [RegEx] Regexp > Récupérer la nième <option> d'un <select id="x">
    Par Sylvain Leray dans le forum Langage
    Réponses: 11
    Dernier message: 18/04/2012, 18h16
  3. [RegExp] Récupérer la valeur qui a matché
    Par need2learn dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 21/01/2009, 17h32
  4. RegExp: Récupérer une valeur en début de chaine
    Par pekka77 dans le forum Langage
    Réponses: 8
    Dernier message: 23/08/2006, 16h07
  5. Réponses: 8
    Dernier message: 02/11/2005, 14h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo