[OFFICE 365] :: REGEX.TEST, REGEX.EXTRAIRE, REGEX.REMPLACER - Utiliser les expressions régulières sous EXCEL via ces fonctions

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

oguruma

XLDnaute Impliqué
Bonjour Le Forum,

Je vous présente quelques expressions régulières à travers les fonctions citées en objet.

Attention il faut absolument être sous Office 365 ou toutes versions ayant ces fonctions.

Ayant eu recours à celles-ci à travers divers développements dans le monde UNIX/AIX/LINUX via les langages SHELL, C_SHELL, PERL, Perl et aussi avec jMeter (outil de tests de perf) autant donc en faire profiter les internautes frileux d'utiliser cette syntaxe un peu barbare. Un exemple d'utilisation classique : avec les commandes GREP, SED, AWK, VI des Unixiens ou Linuxiens.

L'utilisation de celles-ci peut éviter de devoir écrire des UDF (User Define Function).

Quelques exemples classiques pour intervenir sur des fichiers :
grep '^$' donnees.txt ==> lignes vides
grep -v '^#' conf.ini ==> exclure les commentaires
et quand on surveille des fichiers de log en extraire par exemple les @ip : grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' run_20260501.log
Je m'arrête là, ce n'est pas le but ici. Mais parcourir un fichier de log en VBA et en extraire toutes les adresses @ip c'est une autre paire de "manches". En Perl ou en shell voir awk c'est un jeu d'enfant (10 lignes max si on veut faire propre et mettre des commentaires avec passage de paramètres).

Les exemples présentés dans le fichier pourront être transposés dans d'autres cas d'utilisations selon vos besoins.

Les formats de données testés sont
1777716072980.png


Les cas d'exemples présentés ne sont pas exhaustifs. Les lecteurs pourront s'en inspirer pour en créer d'autres.

J'ai placé aussi quelques règles élémentaires. Pour autant celles-ci sont largement documentées sur le net ou dans des littératures spécialisées. Inutile donc de faire un doublon.

Les données générées dans le fichier sont totalement fictives. Je suis passé par quelques lignes VBA pour les créer de manière aléatoire.

Quelques extraits :
1777716269591.png


1777716311057.png


1777716346408.png


1777716374106.png


1777716421393.png


1777716954116.png
 

Pièces jointes

Bonjour @oguruma
et pour ceux qui n'ont pas les fonctions regex dans excel
on laisse les formules tel quel et on fait les mêmes en vba
VB:
Function REGEXTEST(Texte, patternx) As Boolean
    'patricktoulon
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .pattern = patternx
        REGEXTEST = .test(CStr(Texte))
    End With
End Function
'
Function REGEXEXTRACT(Texte, patternx) As String
    'patricktoulon
    Dim matches
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .pattern = patternx
        Set matches = .Execute(CStr(Texte))
        If matches.Count > 0 Then REGEXEXTRACT = matches(0)
    End With
End Function
'
Function REGEXREPLACE(Texte, patternx, remplace) As String
    'patricktoulon
    Dim matches
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .pattern = patternx
        Set matches = .Execute(CStr(Texte))
        If matches.Count > 0 Then REGEXREPLACE = Replace(CStr(Texte), matches(0), remplace)
    End With
End Function
 
Bonjour @oguruma
et pour ceux qui n'ont pas les fonctions regex dans excel
on laisse les formules tel quel et on fait les mêmes en vba
VB:
Function REGEXTEST(Texte, patternx) As Boolean
    'patricktoulon
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .pattern = patternx
        REGEXTEST = .test(CStr(Texte))
    End With
End Function
'
Function REGEXEXTRACT(Texte, patternx) As String
    'patricktoulon
    Dim matches
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .pattern = patternx
        Set matches = .Execute(CStr(Texte))
        If matches.Count > 0 Then REGEXEXTRACT = matches(0)
    End With
End Function
'
Function REGEXREPLACE(Texte, patternx, remplace) As String
    'patricktoulon
    Dim matches
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .pattern = patternx
        Set matches = .Execute(CStr(Texte))
        If matches.Count > 0 Then REGEXREPLACE = Replace(CStr(Texte), matches(0), remplace)
    End With
End Function
Bonjour Patrick, ainsi tout le monde est servi. Plu
Bonjour @oguruma
et pour ceux qui n'ont pas les fonctions regex dans excel
on laisse les formules tel quel et on fait les mêmes en vba
VB:
Function REGEXTEST(Texte, patternx) As Boolean
    'patricktoulon
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .pattern = patternx
        REGEXTEST = .test(CStr(Texte))
    End With
End Function
'
Function REGEXEXTRACT(Texte, patternx) As String
    'patricktoulon
    Dim matches
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .pattern = patternx
        Set matches = .Execute(CStr(Texte))
        If matches.Count > 0 Then REGEXEXTRACT = matches(0)
    End With
End Function
'
Function REGEXREPLACE(Texte, patternx, remplace) As String
    'patricktoulon
    Dim matches
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .pattern = patternx
        Set matches = .Execute(CStr(Texte))
        If matches.Count > 0 Then REGEXREPLACE = Replace(CStr(Texte), matches(0), remplace)
    End With
End Function
Bonjour Patrick,
Ainsi tout le monde est servi ! Et plus aucune excuse pour ne pas se mettre aux expressions régulières 😉 merci
 
Bonjour @oguruma
et pour ceux qui n'ont pas les fonctions regex dans excel
on laisse les formules tel quel et on fait les mêmes en vba
VB:
Function REGEXTEST(Texte, patternx) As Boolean
    'patricktoulon
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .pattern = patternx
        REGEXTEST = .test(CStr(Texte))
    End With
End Function
'
Function REGEXEXTRACT(Texte, patternx) As String
    'patricktoulon
    Dim matches
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .pattern = patternx
        Set matches = .Execute(CStr(Texte))
        If matches.Count > 0 Then REGEXEXTRACT = matches(0)
    End With
End Function
'
Function REGEXREPLACE(Texte, patternx, remplace) As String
    'patricktoulon
    Dim matches
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .pattern = patternx
        Set matches = .Execute(CStr(Texte))
        If matches.Count > 0 Then REGEXREPLACE = Replace(CStr(Texte), matches(0), remplace)
    End With
End Function
Rebonjour Patrick,
Bon dans le Nord c'est l'orage donc autant faire du VBA 🙂
J'ai intégré tes 3 fonctions dans une version plus réduite. Au moins les internautes auront une version clef en main.
Cependant je suis intervenu sur la fonction Function REGEXEXTRACT(Texte, patternx) As String pour en faire une V2.
Bon elle est "brute de cash" il faudrait peut-être encore la blinder.
En effet, sous Excel il faut tenir compte d'une option =REGEX.EXTRAIRE([@Secu]; "^[12]([0-9]{2})"; 2 ) ==> option 2
1777811153523.png


Voici donc un bout de code corrigé.
Il faut tenir compte du SubMatches (matches(0).SubMatches.Count) afin de simuler le mode_renvoi de Excel.
C'est ce qui me semble le meilleur deal pour traiter cela... si tu vois une autre possibilité, je suis preneur.

VB:
Function REGEXEXTRACT_V2(Texte As Variant, patternx As String, Optional return_mode As Integer = 0) As Variant
'*******************************************
' 02/05/2026 - V1.0 Patricktoulon -XLD
' 03/05/2026 - V2.0 Oguruma - XLD
'********************************************

    '****************************************************************************************
    'Info :  return_mode : 0 = Le Match complet (par défaut), 2 = Premier groupe de capture
    '****************************************************************************************
    
    Dim matches As Object
    
    Dim reg As Object
    
    Set reg = CreateObject("VBScript.RegExp")
    
    With reg
        '********************************************************
        '* On le passe à FALSE pour gérer l'option 2 chez Excel
        '********************************************************
        .Global = False
        .IgnoreCase = True
        .Pattern = patternx
        
        Set matches = .Execute(CStr(Texte))
        
        If matches.Count > 0 Then
            ' ******************************************
            ' * Option 2 de la fonction sous EXCEL
            ' ******************************************
            If return_mode = 2 Then
                If matches(0).SubMatches.Count > 0 Then
                    '*************************************
                    '* Là il faut renvoyer le 1er groupe
                    '*************************************
                    REGEXEXTRACT_V2 = matches(0).SubMatches(0)
                Else
                    '******************************************
                    '* On n'a pas trouvé de groupe
                    '******************************************
                    REGEXEXTRACT_V2 = matches(0).Value
                End If
            Else
                '**********************************************************
                '* Et dans les autres cas on renvoie la totalité du Match
                '**********************************************************
                REGEXEXTRACT_V2 = matches(0).Value
            End If
        Else
            '******************************************
            '* Cas du #N/A renvoyé par Excel au cas où
            '******************************************
            REGEXEXTRACT_V2 = ""
        End If
    End With
End Function

Function REGEXREPLACE(Texte, patternx, remplace) As String
    'patricktoulon
    Dim matches
    With CreateObject("VBScript.RegExp"):
        .Global = True: .IgnoreCase = True: .Pattern = patternx
        Set matches = .Execute(CStr(Texte))
        If matches.Count > 0 Then REGEXREPLACE = Replace(CStr(Texte), matches(0), remplace)
    End With
End Function

1777811454852.png


1777811491704.png


1777811511229.png


Les autres fonctions REPLACE et TEST fonctionnent.
1777811589220.png


Bon dimanche dans le sud.
 

Pièces jointes

re
bonjour
oui je l'ai vu après le 3eme argument

du coup j'ai pensé a un truc
en faire une avec des spécificité ou pas avec selection de matches ou pas et submatches ou pas
les spécificités serait dans les cases
dans le case else la raison devient le pattern
un peu dans ce genre là
VB:
'=RegexExtractType(A1;"secu";1;1)'sexe
'=RegexExtractType(A1;"secu";1;2)'année
'=RegexExtractType(A1;"secu";1;3)'mois
'=RegexExtractType(A1;"secu";1;4)'departement
'etc...

Function RegexExtractType(ByVal Texte As String, ByVal raison As String, Optional M_occur As Long = -1, Optional ByVal SubMindex As Long = -1) As String
    
    Dim regex As Object, regExtract As Object, matches As Object, available As Boolean, m As Object
    
    Set regex = CreateObject("VBScript.RegExp")
    With regex
        .IgnoreCase = True
        .Global = True
        
        ' =========================
        ' VALIDATION PAR TYPE
        ' =========================
        Select Case raison
                
            Case "mail", 1
                
            Case "secu", 2
                ' Numéro de sécu FR (simplifié)
                ' 13 chiffres + clé
                .Pattern = "^([12])(\d{2})(\d{2})(\d{2})(\d{3})(\d{3})(\d{2})"
                
                
            Case "num"
                
            Case Else
                .Pattern = raison
                'le pattern c'est la raison
        End Select
        available = .Test(Texte)
              
        ' =========================
        ' EXTRACTION
        ' =========================
        If available Then 'si on a passé le test
            Set matches = .Execute(Texte)
            Debug.Print matches.Count
            If matches.Count > 0 Then 'si on a des matches
                If M_occur > 0 Then
                    Set m = matches(M_occur - 1) 'on est en base 1 dans l'argumenttation donc -1
                   Debug.Print m.Value
                Else
                    Set m = matches(0) 'on est en base 1 dans l'argumenttation donc -1
                End If
              
             If Not m Is Nothing Then RegexExtractType = m.Value
    
               If SubMindex > 0 Then
                    'pour les demandes de groupe
                    If m.submatches.Count > 0 Then
                     Debug.Print m.submatches.Count
                      Debug.Print m.submatches(SubMindex - 1)
                        If SubMindex <= m.submatches.Count Then RegexExtractType = m.submatches(SubMindex - 1)
                    End If
                    
                    
                End If
                
                
            End If
        End If
    End With
                
End Function
c'est un truc a main levée là la secu c'est bon
reste plus qu'a ajouter des spé ou s'en servir avec un pattern
 
re
bonjour
oui je l'ai vu après le 3eme argument

du coup j'ai pensé a un truc
en faire une avec des spécificité ou pas avec selection de matches ou pas et submatches ou pas
les spécificités serait dans les cases
dans le case else la raison devient le pattern
un peu dans ce genre là
VB:
'=RegexExtractType(A1;"secu";1;1)'sexe
'=RegexExtractType(A1;"secu";1;2)'année
'=RegexExtractType(A1;"secu";1;3)'mois
'=RegexExtractType(A1;"secu";1;4)'departement
'etc...

Function RegexExtractType(ByVal Texte As String, ByVal raison As String, Optional M_occur As Long = -1, Optional ByVal SubMindex As Long = -1) As String
   
    Dim regex As Object, regExtract As Object, matches As Object, available As Boolean, m As Object
   
    Set regex = CreateObject("VBScript.RegExp")
    With regex
        .IgnoreCase = True
        .Global = True
       
        ' =========================
        ' VALIDATION PAR TYPE
        ' =========================
        Select Case raison
               
            Case "mail", 1
               
            Case "secu", 2
                ' Numéro de sécu FR (simplifié)
                ' 13 chiffres + clé
                .Pattern = "^([12])(\d{2})(\d{2})(\d{2})(\d{3})(\d{3})(\d{2})"
               
               
            Case "num"
               
            Case Else
                .Pattern = raison
                'le pattern c'est la raison
        End Select
        available = .Test(Texte)
             
        ' =========================
        ' EXTRACTION
        ' =========================
        If available Then 'si on a passé le test
            Set matches = .Execute(Texte)
            Debug.Print matches.Count
            If matches.Count > 0 Then 'si on a des matches
                If M_occur > 0 Then
                    Set m = matches(M_occur - 1) 'on est en base 1 dans l'argumenttation donc -1
                   Debug.Print m.Value
                Else
                    Set m = matches(0) 'on est en base 1 dans l'argumenttation donc -1
                End If
             
             If Not m Is Nothing Then RegexExtractType = m.Value
   
               If SubMindex > 0 Then
                    'pour les demandes de groupe
                    If m.submatches.Count > 0 Then
                     Debug.Print m.submatches.Count
                      Debug.Print m.submatches(SubMindex - 1)
                        If SubMindex <= m.submatches.Count Then RegexExtractType = m.submatches(SubMindex - 1)
                    End If
                   
                   
                End If
               
               
            End If
        End If
    End With
               
End Function
c'est un truc a main levée là la secu c'est bon
reste plus qu'a ajouter des spé ou s'en servir avec un pattern
re, si je comprends ta proposition on peut partir sur du spécifique optionnel comme n° de secu, iban, rib, immat figer en "dur" les pattern (comme .Pattern = "^([12])(\d{2})(\d{2})(\d{2})(\d{3})(\d{3})(\d{2})") dans le code sinon pour les autres cas préciser le pattern pour des extractions qui ne répondent pas à des formats connus. Bon pour la partie financière il faut faire attention avec la vérification avec la formule de Luhn 15 années d'expérience en banque... je sais de quoi je parle.... et je crois aussi utilisée dans les assurances.... c'est du modulo 10 mais ça fait un bail que je n'ai pas mis le nez là-dedans 😉

Mais en effet ce que tu proposes si j'ai bien capté pourrait être une évolution peut-être à mettre sous forme de classe 😉 bon je sais que tu n'es pas très friand je crois du développement par les classes...
 
tu rigole i 'me the king of classe
mais en l’occurrence ici pas besoins le select case suffit (mais on pourrait pour tordre le truc au bout du bout )
le truc intéressant dans ma propositions aussi c'est matches ou submatches ou les deux car elle le gère
on peut chercher une /des occurrences dans une chaine
ou
chercher une partie d'une occurence avec les submatches
ça ma fonction le gère en fonction du pattern déjà

exemple c'est pour ca que j'ai volontairement fait des groupes(...)(...)(...) dans le pattern de "secu"
sinon pour un numéro de secu j'aurais fait "^([12]\d{14}}"
matches(x) trouve la ou les occurrences complète 15 chiffres si on a la cléavec sinon 13
et le subMindex indique que l'on veut une partie de
et les submatches correspondent parfaitement au groupes
autrement dit c'est un regex passe partout multi mode All pattern and Spé

tiens voici le mail
VB:
'=RegexExtractType(A1;"secu";1;1)'sexe
'=RegexExtractType(A1;"secu";1;2)'année
'=RegexExtractType(A1;"secu";1;3)'mois
'=RegexExtractType(A1;"secu";1;4)'departement
'etc...
'=RegexExtractType($A4;"mail";0;1)'nom ou prenom ou les deux si accroché
'=RegexExtractType($A4;"mail";0;2)'prenom ou ou vide  si les deux sont accroché et donc tombé dans le (1)
'=RegexExtractType($A4;"mail";0;3)'domaine
'=RegexExtractType($A4;"mail";0;4)'extension

Function RegexExtractType(ByVal Texte As String, ByVal raison As String, Optional M_occur As Long = -1, Optional ByVal SubMindex As Long = -1) As String
 
    Dim regex As Object, regExtract As Object, matches As Object, available As Boolean, m As Object
 
    Set regex = CreateObject("VBScript.RegExp")
    With regex
        .IgnoreCase = True
        .Global = True
     
        ' =========================
        ' VALIDATION PAR TYPE
        ' =========================
        Select Case raison
             
            Case "mail", 1
                 '(nom) ,(peut être un separateur) , (prenom) , (domaine ou FAI) , (extension)
                 .Pattern = "^([a-zA-ZÀ-ÿ]+)(?:[\.\-_]([a-zA-ZÀ-ÿ]+))?@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$"
           
            Case "secu", 2
                ' Numéro de sécu FR (simplifié)
                ' 13 chiffres + clé
                .Pattern = "^([12])(\d{2})(\d{2})(\d{2})(\d{3})(\d{3})(\d{2})"
             
             
            Case "num"
             
            Case Else
                .Pattern = raison
                'le pattern c'est la raison
        End Select
        available = .Test(Texte)
           
        ' =========================
        ' EXTRACTION
        ' =========================
        If available Then 'si on a passé le test
            Set matches = .Execute(Texte)
            Debug.Print matches.Count
            If matches.Count > 0 Then 'si on a des matches
                If M_occur > 0 Then
                    Set m = matches(M_occur - 1) 'on est en base 1 dans l'argumenttation donc -1
                   Debug.Print m.Value
                Else
                    Set m = matches(0) 'on est en base 1 dans l'argumenttation donc -1
                End If
           
             If Not m Is Nothing Then RegexExtractType = m.Value
 
               If SubMindex > 0 Then
                    'pour les demandes de groupe
                    If m.submatches.Count > 0 Then
                     Debug.Print m.submatches.Count
                      Debug.Print m.submatches(SubMindex - 1)
                        If SubMindex <= m.submatches.Count Then RegexExtractType = m.submatches(SubMindex - 1)
                    End If
                 
                 
                End If
             
             
            End If
        End If
    End With
             
End Function
vise un peu l'artiste
1777833739590.png


autrement dit avec le conditionnel du separateur en l'incluant dans le groupe 2 mon indexation de recherche ne change pas
le 1 c'est le nom ou prénom
le 2 c'est le 2d nom ou prénom ou vide si pas de séparateur
le 3 c'est le domaine
le 4 c'est l'extension de domaine

et ca marcherait aussi bien si je faisait
=RegexExtractType($A4;"^([a-zA-ZÀ-ÿ]+)(?:[\.\-_]([a-zA-ZÀ-ÿ]+))?@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$";0;1)

voila
edit😛our que mon intention soit comprises
=RegexExtractType($A4;(pattern ou raison) , Neme matches 'occurence (N) dans une chaine
=RegexExtractType($A4;(pattern ou raison) , Neme matches , Neme submaches 'sous groupe(N) dans uneoccurence(N)


il suffit de mettre les argument ou pas dans l'appel
 
Dernière édition:
tu rigole i 'me the king of classe
mais en l’occurrence ici pas besoins le select case suffit (mais on pourrait pour tordre le truc au bout du bout )
le truc intéressant dans ma propositions aussi c'est matches ou submatches ou les deux car elle le gère
on peut chercher une /des occurrences dans une chaine
ou
chercher une partie d'une occurence avec les submatches
ça ma fonction le gère en fonction du pattern déjà

exemple c'est pour ca que j'ai volontairement fait des groupes(...)(...)(...) dans le pattern de "secu"
matches(x) trouve la ou les occurrences complète 15 chiffres si on a la cléavec sinon 13
et le subMindex indique que l'on veut une partie de
et les submatches correspondent parfaitement au groupes
autrement dit c'est un regex passe partout multi mode All pattern and Spé

tiens voici le mail
VB:
'=RegexExtractType(A1;"secu";1;1)'sexe
'=RegexExtractType(A1;"secu";1;2)'année
'=RegexExtractType(A1;"secu";1;3)'mois
'=RegexExtractType(A1;"secu";1;4)'departement
'etc...
'=RegexExtractType($A4;"mail";0;1)'nom ou prenom ou les deux si accroché
'=RegexExtractType($A4;"mail";0;2)'prenom ou ou vide  si les deux sont accroché et donc tombé dans le (1)
'=RegexExtractType($A4;"mail";0;3)'domaine
'=RegexExtractType($A4;"mail";0;4)'extension

Function RegexExtractType(ByVal Texte As String, ByVal raison As String, Optional M_occur As Long = -1, Optional ByVal SubMindex As Long = -1) As String
  
    Dim regex As Object, regExtract As Object, matches As Object, available As Boolean, m As Object
  
    Set regex = CreateObject("VBScript.RegExp")
    With regex
        .IgnoreCase = True
        .Global = True
      
        ' =========================
        ' VALIDATION PAR TYPE
        ' =========================
        Select Case raison
              
            Case "mail", 1
                 '(nom) ,(peut être un separateur) , (prenom) , (domaine ou FAI) , (extension)
                 .Pattern = "^([a-zA-ZÀ-ÿ]+)(?:[\.\-_]([a-zA-ZÀ-ÿ]+))?@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$"
            
            Case "secu", 2
                ' Numéro de sécu FR (simplifié)
                ' 13 chiffres + clé
                .Pattern = "^([12])(\d{2})(\d{2})(\d{2})(\d{3})(\d{3})(\d{2})"
              
              
            Case "num"
              
            Case Else
                .Pattern = raison
                'le pattern c'est la raison
        End Select
        available = .Test(Texte)
            
        ' =========================
        ' EXTRACTION
        ' =========================
        If available Then 'si on a passé le test
            Set matches = .Execute(Texte)
            Debug.Print matches.Count
            If matches.Count > 0 Then 'si on a des matches
                If M_occur > 0 Then
                    Set m = matches(M_occur - 1) 'on est en base 1 dans l'argumenttation donc -1
                   Debug.Print m.Value
                Else
                    Set m = matches(0) 'on est en base 1 dans l'argumenttation donc -1
                End If
            
             If Not m Is Nothing Then RegexExtractType = m.Value
  
               If SubMindex > 0 Then
                    'pour les demandes de groupe
                    If m.submatches.Count > 0 Then
                     Debug.Print m.submatches.Count
                      Debug.Print m.submatches(SubMindex - 1)
                        If SubMindex <= m.submatches.Count Then RegexExtractType = m.submatches(SubMindex - 1)
                    End If
                  
                  
                End If
              
              
            End If
        End If
    End With
              
End Function
vise un peu l'artiste
Regarde la pièce jointe 1230000

autrement dit avec le conditionnel du separateur en l'incluant dans le groupe 2 mon indexation de recherche ne change pas
le 1 c'est le nom ou prénom
le 2 c'est le 2d nom ou prénom ou vide si pas de séparateur
le 3 c'est le domaine
le 4 c'est l'extension de domaine

et ca marcherait aussi bien si je faisait
=RegexExtractType($A4;"^([a-zA-ZÀ-ÿ]+)(?:[\.\-_]([a-zA-ZÀ-ÿ]+))?@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$";0;1)

voila
edit😛our que mon intention soit comprises
=RegexExtractType($A4;(pattern ou raison) , Neme matches 'occurence (N) dans une chaine
=RegexExtractType($A4;(pattern ou raison) , Neme matches , Neme submaches 'sous groupe(N) dans uneoccurence(N)


il suffit de mettre les argument ou pas dans l'appel
bonnnn bin ne plus qu'à packager... ou laisser en l'état....
pour les noms dans les emails tu as prévu loin y compris les caractères accentués.. pas courant ces types d'adresses
 
a ben je vais au bout du bout je prévois tout 😅😂😂
donne moi une chaine avec sa règle et je te fait le pattern sous forme de groupe valable pour matches(x) ou (maches(x).submatches(y)
 
a ben je vais au bout du bout je prévois tout 😅😂😂
donne moi une chaine avec sa règle et je te fait le pattern sous forme de groupe valable pour matches(x) ou (maches(x).submatches(y)
je travaille sur une nouvelle publication qui va bientôt sortir avant ce soir : RegEx et PowerQuery en simulant l'exploitation d'un fichier de log.... avec ce format d'enregistement...

Voici de quoi passer ta soirée 😉
SRV-PROD-01-BIS eMail address <root@internal.local> @Ip Address [172.16.254.1] Application {SAP} ID_TRANSACTION [ID-2960]

L'enregistrement complet se présente comme suit (bon totalement imaginaire) ; dans bien des cas on retrouve ce type d'info dans des fichiers de log... bon sous AIX/Linux je passais par GREP soit avec un peu de Perl soit avec un peu shell

2026-05-03 14:18:03;SRV-PROD-01-BIS eMail address <root@internal.local> @Ip Address [172.16.254.1] Application {SAP} ID_TRANSACTION [ID-2960]

je te laisse deviner quelles seraient les données à extraire pour les placer dans une colonne propre à chaque donnée.
Je ne vais pas intégrer ta dernière version dans mon fichier Excel, je t'en laisser l'honneur et la primeur 😉
 
Bonjour Patrick, on pourra dire que nos contributions construites à la volée vont constituer une belle caisse à outils pour les membres du forum et les internautes qui passent par XLD. Ils ont désormais une large panoplie d'outils pour extraire des données d'une chaine de caractères quelque soit leur version d'Excel. Certains diront peut-être que pour rechercher une date, une heure, un serveur... ils ont fait compliqué 🙂 mais le but était d'introduire l'utilisation des expressions régulières pour extraire des données sachant qu'il n'y a jamais de solutions universelles.
Je te laisse la liberté de reprendre mon dernier fichier Excel publié hier soir pour packager ta dernière fonction en y intégrant les exemples que tu as traité hier soir.
Bonne journée. Merci pour cette participation fructueuse. J'estime que l'on peut en rester là pour le moment.
 
Dernière édition:
Rebonjour Patrick,
j'ai toutefois intégré ton code à des fins de tests dans mon dernier fichier Excel.
J'ai ajouté deux raisons : ip1 et ip2.

Voici la dernière version du code dans laquelle j'ai ajouté ces deux raisons

VB:
Function RegexExtractType(ByVal Texte As String, ByVal raison As String, Optional M_occur As Long = -1, Optional ByVal SubMindex As Long = -1) As String
'**************************************************************************************************
'* AUTEUR VERSION ORIGINALE - 03/05/2026 : P. TOULON (XLD)
'* ADAPTATION ET INTEGRATION - 04/05/206 : OGURUMA (XLD)
'**************************************************************************************************
 
    Dim regex As Object, regExtract As Object, matches As Object, available As Boolean, m As Object
 
    Set regex = CreateObject("VBScript.RegExp")
    With regex
        .IgnoreCase = True
        .Global = True
 
        ' =========================
        ' VALIDATION PAR TYPE
        ' =========================
        Select Case LCase(raison)
         
            Case "mail", 1
                 '(nom) ,(peut être un separateur) , (prenom) , (domaine ou FAI) , (extension)
                 .Pattern = "^([a-zA-ZÀ-ÿ]+)(?:[\.\-_]([a-zA-ZÀ-ÿ]+))?@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$"
       
            Case "secu", 2
                ' Numéro de sécu FR (simplifié)
                ' 13 chiffres + clé
                .Pattern = "^([12])(\d{2})(\d{2})(\d{2})(\d{3})(\d{3})(\d{2})"
             
                ' 04/05/2026 - Oguruma - Ajout de la raison ip version 1
            Case "ip1", 3
                .Pattern = "(\d+\.\d+\.\d+\.\d+)"
             
                ' 04/05/2026 - Oguruma - Ajout de la raison ip version 2
            Case "ip2", 4
                .Pattern = "\[(\d+\.\d+\.\d+\.\d+)\]"
             
            Case "num"
         
            Case Else
                .Pattern = raison
                'le pattern c'est la raison
        End Select
        available = .Test(Texte)
       
        ' =========================
        ' EXTRACTION
        ' =========================
        If available Then 'si on a passé le test
            Set matches = .Execute(Texte)
            Debug.Print matches.Count
            If matches.Count > 0 Then 'si on a des matches
                If M_occur > 0 Then
                    Set m = matches(M_occur - 1) 'on est en base 1 dans l'argumenttation donc -1
                   Debug.Print m.Value
                Else
                    Set m = matches(0) 'on est en base 1 dans l'argumenttation donc -1
                End If
       
             If Not m Is Nothing Then RegexExtractType = m.Value
               If SubMindex > 0 Then
                    'pour les demandes de groupe
                    If m.SubMatches.Count > 0 Then
                     Debug.Print m.SubMatches.Count
                      Debug.Print m.SubMatches(SubMindex - 1)
                        If SubMindex <= m.SubMatches.Count Then RegexExtractType = m.SubMatches(SubMindex - 1)
                    End If
                End If
            End If
        End If
    End With
         
End Function

Les Debug.Print ont été mis en commentaires dans le fichier pour aller un peu plus vite.

Dans le fichier joint tu trouveras les tests que j'ai réalisé.
1777902007447.png


=RegexExtractType([@RawData];"ip1")

1777902072930.png


1777902093337.png


1777902116850.png


Le plus simple voir le fichier Excel. J'en reste là. Ce code t'appartient.
 

Pièces jointes

Dernière édition:
et date heure alors?
case "dateUS": pattern="(\d{4}[^\w]\d{2}[^\w]\d{2}\s)(\d{2}[^\w]\d{2}[^\w]\d{2})"
case "dateFR": pattern="(\d{2}[^\w]\d{2}[^\w]\d{4}\s)(\d{2}[^\w]\d{2}[^\w]\d{2})"
le pattern renvois en matches(0) la date et heure
le submatches 0 et 1 renvoie les deux composantes
conclusion


2026-05-03 14:18:03;SRV-PROD-01-BIS eMail address <root@internal.local> @Ip Address [172.16.254.1] Application {SAP} ID_TRANSACTION [ID-2960]

SRV-PROD-01-BIS eMail address <root@internal.local> Application {SAP} ID_TRANSACTION [ID-2960] ;2026-05-03 14:18:03;@Ip Address [172.16.254.1]




date--> =RegexExtractType(A7;"dateUS";1;1)
heure--> =RegexExtractType(A7;"dateUS";1;2)
addresse ip -->=RegexExtractType(A7;"(\d{3}[^\w]\d{2}[^\w]\d{3}[^\w]\d{1})")
mail:-->=RegexExtractType(A7;"(\s[^\w|])(\D+@\D+)([^\w|]\s)";1;2)

voila des fois vaut mieux prendre plus en faisant des groupes et selectionner un sub ,c'est plus facile qu'un matches tout court
pour l'address ip je remplace le "." par un caractère special au cas ou çà serait présenté différemment

bref aucun soucis avec ta ligne de texte
 
et date heure alors?
case "dateUS": pattern="(\d{4}[^\w]\d{2}[^\w]\d{2}\s)(\d{2}[^\w]\d{2}[^\w]\d{2})"
case "dateFR": pattern="(\d{2}[^\w]\d{2}[^\w]\d{4}\s)(\d{2}[^\w]\d{2}[^\w]\d{2})"
le pattern renvois en matches(0) la date et heure
le submatches 0 et 1 renvoie les deux composantes
conclusion









date--> =RegexExtractType(A7;"dateUS";1;1)
heure--> =RegexExtractType(A7;"dateUS";1;2)
addresse ip -->=RegexExtractType(A7;"(\d{3}[^\w]\d{2}[^\w]\d{3}[^\w]\d{1})")
mail:-->=RegexExtractType(A7;"(\s[^\w|])(\D+@\D+)([^\w|]\s)";1;2)

voila des fois vaut mieux prendre plus en faisant des groupes et selectionner un sub ,c'est plus facile qu'un matches tout court
pour l'address ip je remplace le "." par un caractère special au cas ou çà serait présenté différemment

bref aucun soucis avec ta ligne de texte
Oui l'heure... la date.... en effet... tu en as la primeur. Mais laissons aussi nos futurs lecteurs se creuser un peu les neurones nous n'allons pas tout faire.... hein ?
Oui j'ai vu ton code est robuste. Perso j'en reste là.
On pourrait pousser le vice un peu plus loin sur toutes formes d'enregistrement de ces données dans un fichier de log ou autres... je t'en laisse le plaisir de tester.
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD
Retour