Comment utiliser des expressions régulières dans Excel et tirer parti de la puissante configuration de type grille d'Excel pour la manipulation de données?
Je comprends que Regex n’est pas idéal dans de nombreuses situations ( tiliser ou ne pas utiliser d’expressions régulières? ), car Excel peut utiliser Left
, Mid
, Right
, Instr
commandes de type pour des manipulations similaires.
Les expressions régulières sont utilisées pour la correspondance de modèle.
Pour utiliser dans Excel, procédez comme suit:
Étape 1 : ajoutez une référence VBA à "Microsoft VBScript Regular Expressions 5.5"
Étape 2 : Définissez votre modèle
Définitions de base:
-
Plage.
a-z
correspond aux lettres minuscules de a à z0-5
correspond à un nombre quelconque compris entre 0 et 5[]
Faites correspondre exactement l'un des objets à l'intérieur de ces crochets.
[a]
correspond à la lettre a[abc]
correspond à une seule lettre qui peut être a, b ou c[a-z]
correspond à n'importe quelle lettre minuscule de l'alphabet.()
Regroupe différentes correspondances à des fins de retour. Voir les exemples ci-dessous.
{}
Multiplicateur pour les copies répétées du motif défini avant.
[a]{2}
correspond à deux lettres minuscules consécutives a: aa
[a]{1,3}
correspond à au moins une et jusqu'à trois lettres minuscules a
, aa
, aaa
+
Faites correspondre au moins un, ou plusieurs, du motif défini avant.
a+
correspondra à un a
, aa
, aaa
, et ainsi de suite?
Correspond à zéro ou à l'un des motifs définis avant.
[a-z]?
correspond à une chaîne vide ou à une seule lettre minuscule.*
Correspond à zéro ou plus du motif défini avant. - Par exemple. Caractère générique pour un motif qui peut ou peut ne pas être présent. - Par exemple. [a-z]*
correspond à une chaîne vide ou à une chaîne de minuscules.
.
Correspond à n'importe quel caractère sauf la nouvelle ligne \n
a.
Correspond à une chaîne de deux caractères commençant par a et se terminant par rien sauf \n
|
OR opérateur
a|b
signifie que a
ou b
peuvent être appariés.red|white|orange
correspond exactement à l'une des couleurs.^
opérateur NON
[^0-9]
ne peut pas contenir de nombre[^aA]
ne peut pas être en minuscule a
ni en majuscule A
\
Échappe au caractère spécial qui suit (annule le comportement ci-dessus)
\.
, \\
, \(
, \?
, \$
, \^
Modèles d'ancrage:
^
La correspondance doit avoir lieu au début de la chaîne.
^a
Le premier caractère doit être en minuscule a
^[0-9]
Le premier caractère doit être un nombre.$
La correspondance doit avoir lieu à la fin de la chaîne.
a$
Le dernier caractère doit être en minuscule a
Table de priorité:
Order Name Representation
1 Parentheses ( )
2 Multipliers ? + * {m,n} {m, n}?
3 Sequence & Anchors abc ^ $
4 Alternation |
Abréviations de caractères prédéfinis:
abr same as meaning
\d [0-9] Any single digit
\D [^0-9] Any single character that's not a digit
\w [a-zA-Z0-9_] Any Word character
\W [^a-zA-Z0-9_] Any non-Word character
\s [ \r\t\n\f] Any space character
\S [^ \r\t\n\f] Any non-space character
\n [\n] New line
Exemple 1 : Exécuter en tant que macro
L'exemple de macro suivant examine la valeur dans la cellule A1
pour voir si les 1 ou 2 premiers caractères sont des chiffres. Si c'est le cas, ils sont supprimés et le reste de la chaîne est affiché. Si ce n'est pas le cas, un message apparaît pour vous indiquer qu'aucune correspondance n'est trouvée. Cellule A1
les valeurs de 12abc
renverront abc
, la valeur de 1abc
renverra abc
, la valeur de abc123
renverra "non apparié" car les chiffres n'étaient pas au début de la chaîne.
Private Sub simpleRegex()
Dim strPattern As String: strPattern = "^[0-9]{1,2}"
Dim strReplace As String: strReplace = ""
Dim regEx As New RegExp
Dim strInput As String
Dim Myrange As Range
Set Myrange = ActiveSheet.Range("A1")
If strPattern <> "" Then
strInput = Myrange.Value
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
If regEx.Test(strInput) Then
MsgBox (regEx.Replace(strInput, strReplace))
Else
MsgBox ("Not matched")
End If
End If
End Sub
Exemple 2 : exécuté en tant que fonction dans la cellule
Cet exemple est identique à l'exemple 1, mais il est configuré pour s'exécuter en tant que fonction dans la cellule. Pour l'utiliser, changez le code en ceci:
Function simpleCellRegex(Myrange As Range) As String
Dim regEx As New RegExp
Dim strPattern As String
Dim strInput As String
Dim strReplace As String
Dim strOutput As String
strPattern = "^[0-9]{1,3}"
If strPattern <> "" Then
strInput = Myrange.Value
strReplace = ""
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
If regEx.test(strInput) Then
simpleCellRegex = regEx.Replace(strInput, strReplace)
Else
simpleCellRegex = "Not matched"
End If
End If
End Function
Placez vos chaînes ("12abc") dans la cellule A1
. Entrez cette formule =simpleCellRegex(A1)
dans la cellule B1
et le résultat sera "abc".
Exemple 3 : Plage de passage en boucle
Cet exemple est identique à l'exemple 1, mais parcourt une plage de cellules.
Private Sub simpleRegex()
Dim strPattern As String: strPattern = "^[0-9]{1,2}"
Dim strReplace As String: strReplace = ""
Dim regEx As New RegExp
Dim strInput As String
Dim Myrange As Range
Set Myrange = ActiveSheet.Range("A1:A5")
For Each cell In Myrange
If strPattern <> "" Then
strInput = cell.Value
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
If regEx.Test(strInput) Then
MsgBox (regEx.Replace(strInput, strReplace))
Else
MsgBox ("Not matched")
End If
End If
Next
End Sub
Exemple 4 : Découper différents motifs
Cet exemple parcourt une plage (A1
, A2
& A3
)) et recherche une chaîne commençant par trois chiffres suivis d'un seul caractère alpha, puis de 4 chiffres. La sortie divise le modèle en correspondances en cellules adjacentes en utilisant le ()
. $1
représente le premier motif correspondant dans le premier ensemble de ()
.
Private Sub splitUpRegexPattern()
Dim regEx As New RegExp
Dim strPattern As String
Dim strInput As String
Dim Myrange As Range
Set Myrange = ActiveSheet.Range("A1:A3")
For Each C In Myrange
strPattern = "(^[0-9]{3})([a-zA-Z])([0-9]{4})"
If strPattern <> "" Then
strInput = C.Value
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
If regEx.test(strInput) Then
C.Offset(0, 1) = regEx.Replace(strInput, "$1")
C.Offset(0, 2) = regEx.Replace(strInput, "$2")
C.Offset(0, 3) = regEx.Replace(strInput, "$3")
Else
C.Offset(0, 1) = "(Not matched)"
End If
End If
Next
End Sub
Résultats:
Exemples de modèles supplémentaires
String Regex Pattern Explanation
a1aaa [a-zA-Z][0-9][a-zA-Z]{3} Single alpha, single digit, three alpha characters
a1aaa [a-zA-Z]?[0-9][a-zA-Z]{3} May or may not have preceeding alpha character
a1aaa [a-zA-Z][0-9][a-zA-Z]{0,3} Single alpha, single digit, 0 to 3 alpha characters
a1aaa [a-zA-Z][0-9][a-zA-Z]* Single alpha, single digit, followed by any number of alpha characters
</i8> \<\/[a-zA-Z][0-9]\> Exact non-Word character except any single alpha followed by any single digit
Pour utiliser des expressions régulières directement dans les formules Excel, la fonction UDF (fonction définie par l'utilisateur) suivante peut être utile. Il expose plus ou moins directement la fonctionnalité d'expression régulière en tant que fonction Excel.
Il faut 2-3 paramètres.
$0
, $1
, $2
, etc. $0
est l'intégralité de la correspondance. $1
et les versions supérieures correspondent aux groupes de correspondance respectifs dans l'expression régulière. La valeur par défaut est $0
.Extraire une adresse email:
=regex("Peter Gordon: [email protected], 47", "\w+@\w+\.\w+")
=regex("Peter Gordon: [email protected], 47", "\w+@\w+\.\w+", "$0")
Résultats en: [email protected]
Extraire plusieurs sous-chaînes:
=regex("Peter Gordon: [email protected], 47", "^(.+): (.+), (\d+)$", "E-Mail: $2, Name: $1")
Résultats en: E-Mail: [email protected], Name: Peter Gordon
Pour séparer une chaîne combinée d'une cellule unique en ses composants en plusieurs cellules:
=regex("Peter Gordon: [email protected], 47", "^(.+): (.+), (\d+)$", "$" & 1)
=regex("Peter Gordon: [email protected], 47", "^(.+): (.+), (\d+)$", "$" & 2)
Résultats en: Peter Gordon
[email protected]
...
Pour utiliser cet UDF, procédez comme suit (à peu près sur la base de cette page Microsoft . Ils ont quelques bonnes informations supplémentaires!):
ALT+F11
pour ouvrir l'éditeur Microsoft Visual Basic pour Applications .Cliquez sur Insérer un module . Si vous attribuez un nom différent à votre module, assurez-vous que celui-ci n'a pas le même nom que le fichier UDF ci-dessous (par exemple, le nom du module Regex
et la fonction regex
cause des erreurs # NAME! ).
Dans la grande fenêtre de texte au milieu, insérez ce qui suit:
Function regex(strInput As String, matchPattern As String, Optional ByVal outputPattern As String = "$0") As Variant
Dim inputRegexObj As New VBScript_RegExp_55.RegExp, outputRegexObj As New VBScript_RegExp_55.RegExp, outReplaceRegexObj As New VBScript_RegExp_55.RegExp
Dim inputMatches As Object, replaceMatches As Object, replaceMatch As Object
Dim replaceNumber As Integer
With inputRegexObj
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = matchPattern
End With
With outputRegexObj
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = "\$(\d+)"
End With
With outReplaceRegexObj
.Global = True
.MultiLine = True
.IgnoreCase = False
End With
Set inputMatches = inputRegexObj.Execute(strInput)
If inputMatches.Count = 0 Then
regex = False
Else
Set replaceMatches = outputRegexObj.Execute(outputPattern)
For Each replaceMatch In replaceMatches
replaceNumber = replaceMatch.SubMatches(0)
outReplaceRegexObj.Pattern = "\$" & replaceNumber
If replaceNumber = 0 Then
outputPattern = outReplaceRegexObj.Replace(outputPattern, inputMatches(0).Value)
Else
If replaceNumber > inputMatches(0).SubMatches.Count Then
'regex = "A to high $ tag found. Largest allowed is $" & inputMatches(0).SubMatches.Count & "."
regex = CVErr(xlErrValue)
Exit Function
Else
outputPattern = outReplaceRegexObj.Replace(outputPattern, inputMatches(0).SubMatches(replaceNumber - 1))
End If
End If
Next
regex = outputPattern
End If
End Function
Enregistrez et fermez la fenêtre de l'éditeur Microsoft Visual Basic pour Applications .
Développer sur patszim 's answer pour ceux qui se précipitent.
ajoutez le code suivant:
Function RegxFunc(strInput As String, regexPattern As String) As String
Dim regEx As New RegExp
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.pattern = regexPattern
End With
If regEx.Test(strInput) Then
Set matches = regEx.Execute(strInput)
RegxFunc = matches(0).Value
Else
RegxFunc = "not matched"
End If
End Function
Le motif de regex est placé dans l'une des cellules et est utilisé comme référence absolue . La fonction sera liée au classeur dans lequel il est créé.
S'il est nécessaire de l'utiliser dans différents classeurs, enregistrez la fonction dans Personal.XLSB .
Voici ma tentative:
Function RegParse(ByVal pattern As String, ByVal html As String)
Dim regex As RegExp
Set regex = New RegExp
With regex
.IgnoreCase = True 'ignoring cases while regex engine performs the search.
.pattern = pattern 'declaring regex pattern.
.Global = False 'restricting regex to find only first match.
If .Test(html) Then 'Testing if the pattern matches or not
mStr = .Execute(html)(0) '.Execute(html)(0) will provide the String which matches with Regex
RegParse = .Replace(mStr, "$1") '.Replace function will replace the String with whatever is in the first set of braces - $1.
Else
RegParse = "#N/A"
End If
End With
End Function
J'avais besoin de l'utiliser comme une fonction de cellule (comme SUM
ou VLOOKUP
) et j'ai trouvé qu'il était facile de:
Créez la fonction suivante dans le classeur ou dans son propre module:
Function REGPLACE(myRange As Range, matchPattern As String, outputPattern As String) As Variant
Dim regex As New VBScript_RegExp_55.RegExp
Dim strInput As String
strInput = myRange.Value
With regex
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = matchPattern
End With
REGPLACE = regex.Replace(strInput, outputPattern)
End Function
Ensuite, vous pouvez utiliser dans la cellule avec =REGPLACE(B1, "(\w) (\d+)", "$1$2")
(ex: "A 243" à "A243")
Voici une fonction regex_subst()
. Exemples:
=regex_subst("watermellon", "[aeiou]", "")
---> wtrmlln
=regex_subst("watermellon", "[^aeiou]", "")
---> aeeo
Voici le code simplifié (plus simple pour moi en tout cas). Je n'arrivais pas à comprendre comment créer un modèle de sortie approprié en utilisant ce qui précède pour fonctionner comme mes exemples:
Function regex_subst( _
strInput As String _
, matchPattern As String _
, Optional ByVal replacePattern As String = "" _
) As Variant
Dim inputRegexObj As New VBScript_RegExp_55.RegExp
With inputRegexObj
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = matchPattern
End With
regex_subst = inputRegexObj.Replace(strInput, replacePattern)
End Function
Je ne veux pas avoir à activer une bibliothèque de référence car j'ai besoin que mes scripts soient portables. La ligne Dim foo As New VBScript_RegExp_55.RegExp
a provoqué des erreurs User Defined Type Not Defined
, mais j'ai trouvé une solution qui fonctionnait pour moi.
Ce que vous voudrez faire est de mettre un exemple de chaîne dans la cellule A1
, puis de tester votre strPattern
. Une fois que cela fonctionne, ajustez alors rng
comme vous le souhaitez.
Public Sub RegExSearch()
'https://stackoverflow.com/questions/22542834/how-to-use-regular-expressions-regex-in-Microsoft-Excel-both-in-cell-and-loops
'https://wellsr.com/vba/2018/Excel/vba-regex-regular-expressions-guide/
'https://www.vitoshacademy.com/vba-regex-in-Excel/
Dim regexp As Object
'Dim regex As New VBScript_RegExp_55.regexp 'Caused "User Defined Type Not Defined" Error
Dim rng As Range, rcell As Range
Dim strInput As String, strPattern As String
Set regexp = CreateObject("vbscript.regexp")
Set rng = ActiveSheet.Range("A1:A1")
For Each rcell In rng.Cells
strPattern = "([a-z]{2})([0-9]{8})"
'Search for 2 ## then 8 Digits Eg: XY12345678 = Matched
If strPattern <> "" Then
strInput = rcell.Value
With regexp
.Global = False
.MultiLine = False
.ignoreCase = True
.Pattern = strPattern
End With
If regexp.test(strInput) Then
MsgBox rcell & " Matched in Cell " & rcell.Address
Else
MsgBox "No Matches!"
End If
End If
Next
End Sub