[VBA] Expressions régulières => Quel pattern ?

Bonjour,

Je suis en ce moment sur le tuto de Caféine concernant les expressions régulières. Je cherche à récupérer pour chaque ligne d'une cellule le contenu d'une parenthèse si et seulement si elle commence par http.

Dans le tutorial le pattern pour extraire les parenthèses dans "Douze travaux d'astérix (les)" est :

(.*) \((.*)\)

Sauf qu'en reproduisant l'exemple dans mon feuillet excel, l'expression ne fonctionne pas !

Le voici :

---------------------------------------------

Dim myRegExp As RegExp
Dim myMatches As MatchCollection
Dim myMatch As Match
Dim monTab() As String
Dim indTab As Integer

Set myRegExp = New RegExp

myRegExp.IgnoreCase = True
myRegExp.Global = True
myRegExp.Pattern = "(.*) \((.*)\)"

Set myMatches = myRegExp.Execute("douze travaux d'Astérix (les)")

For Each myMatch In myMatches
MsgBox myMatch
ReDim Preserve monTab(indTab) 'redimensionnement de la variable tableau
monTab(indTab) = myMatch 'stockage de sa valeur en mémoire
indTab = indTab + 1 'incrémentation de l'indice de la variable tableau
Next

---------------------------------------------

(Je n'ai pas mis de balise code car il ajoute systématiquement un retour à la ligne à chaque ligne à chaque modification...bizarre d'ailleurs...)

Le msgbox renvoie "douze travaux d'Astérix (les)" au lieu de "douze travaux d'Astérix" et "les".

ça me pose un soucis, parce que je comptais utiliser comme pattern pour ma récupération d'url entre parenthèse :

(.*)\((http:\\\\.*)\) qui est *théoriquement* censé me renvoyer :
- Le contenu de la cellule avant parenthèse
- Le contenu de la parenthèse avec le lien www SANS les parenthèses

J'ai forcément oublié un détail, mais je ne sais pas où...quelqu'un a une idée ?

Merci beaucoup !

3 réponses

  1. Contributeur
    Tout fonctionne niquel, merci pour vos réponses rapides, et honte à moi pour mon manque de logique sur ce coup...

    Passez une excellente après-midi !
    1. Contributeur
      Salut lml-mike,

      Ta regexp
      (.*) \((.*)\)
      est bonne pour matcher en premier "douze travaux d'Astérix" et en 2ème "(les)" dans "douze travaux d'Astérix (les)".

      Comme l'indique pijaku, cependant, ton code ne fait visiblement pas ce que propose le tutoriel pour explorer les résultats de execute, qui utilise SubMatches(i) pour récupérer les résultats, dont le nombre est récupéré avec SubMatches.Count. Je ne pratique pas trop VBA, alors, vois la réponse de pijaku sur ce point.

      Dans ton cas, s'il n'y a que le 2ème match qui t'intéresse, tu pourrais juste vérifier que SubMatches.Count renvoie bien 2, et aller directement chercher SubMatches(1).

      Pour ta regexp
      (.*)\((http:\\\\.*)\)
      , je pense que cela serait plutôt
      (.*)\((http://.*)\)
      , car ce sont des slashs qui suivent les : dans une URL et non des anti-slashes (à moins que tes URL ne soient bizarres).

      Dal
      1. Contributeur
        remarque très juste, merci beaucoup !
    2. Modérateur
      Salut,

      Si tu veux récupérer "douze travaux d'Astérix" et "les", il te faut boucler sur les SubMatches de tes Match.
      Dans le tuto de Caféine :
          Set Matches = reg.Execute(strSource)
      
      For Each Match In Matches
      Debug.Print "source >>", Match.Value
      For i = 0 To Match.SubMatches.Count - 1
      Debug.Print "[$" & i + 1 & "]", Match.SubMatches(i)
      Next i
      Next Match

      Dans ton cas :
          Set myMatches = reg.Execute(strSource)
      
      For Each myMatch In myMatches
      MsgBox myMatch.Value
      For i = 0 To myMatch.SubMatches.Count - 1
      ReDim Preserve monTab(indTab)
      monTab(indTab) = myMatch.SubMatches(i)
      MsgBox monTab(indTab)
      indTab = indTab + 1
      Next i
      Next myMatch
      1. Contributeur
        Effectivement, le compteur comme indiqué fonctionne correctement, gros oubli de ma part :/

        Mais, pour info, pourquoi - 1 ?
      2. Modérateur
        pourquoi - 1 ?
        Simple question mathématiques.
        Prenons ton exemple.
        Tu as deux submatches, la n° 0 et la n°1.
        Soit SubMatches.Count est égal à 2.
        Comme nous voulons boucler sur les SubMatches, on initialise la boucle à 0. Comme nous commençons à 0 et qu'il nous faut 2 "tours" de boucle, et que SubMatches.Count = 2, il faut lui enlever 1......
        Ok?