Wie kann ich reguläre Ausdrücke in Excel verwenden und das leistungsstarke rasterähnliche Setup von Excel für die Datenbearbeitung nutzen?
Ich verstehe, dass Regex für viele Situationen nicht ideal ist ( Verwenden oder Nichtverwenden von regulären Ausdrücken? ), da Excel Befehle vom Typ Left
, Mid
, Right
und Instr
für ähnliche Manipulationen verwenden kann.
Reguläre Ausdrücke werden für den Mustervergleich verwendet.
Gehen Sie folgendermaßen vor, um in Excel zu verwenden:
Schritt 1 : VBA-Verweis auf "Microsoft VBScript Regular Expressions 5.5" hinzufügen
Schritt 2 : Definieren Sie Ihr Muster
Grundlegende Definitionen:
-
Bereich.
a-z
stimmt mit Kleinbuchstaben von a bis z überein0-5
entspricht einer beliebigen Zahl von 0 bis 5[]
Entspricht genau einem der Objekte in diesen Klammern.
[a]
stimmt mit dem Buchstaben a überein[abc]
stimmt mit einem einzelnen Buchstaben überein, der a, b oder c sein kann[a-z]
entspricht einem einzelnen Kleinbuchstaben des Alphabets.()
Gruppiert verschiedene Übereinstimmungen für Rückgabezwecke. Siehe Beispiele unten.
{}
Multiplikator für wiederholte Kopien des zuvor definierten Musters.
[a]{2}
entspricht zwei aufeinanderfolgenden Kleinbuchstaben a: aa
[a]{1,3}
entspricht mindestens einem und maximal drei Kleinbuchstaben a
, aa
, aaa
+
Entspricht mindestens einem oder mehreren der zuvor definierten Muster.
a+
stimmt mit dem a
, aa
, aaa
und so weiter überein?
Entspricht keinem oder einem der zuvor definierten Muster.
[a-z]?
entspricht einer leeren Zeichenfolge oder einem einzelnen Kleinbuchstaben.*
Stimmt mit keinem oder mehreren der zuvor definierten Muster überein. - Z.B. Platzhalter für Muster, die möglicherweise vorhanden sind oder nicht. - Z.B. [a-z]*
entspricht einer leeren Zeichenfolge oder einer Zeichenfolge aus Kleinbuchstaben.
.
Stimmt mit jedem Zeichen außer Zeilenvorschub überein \n
a.
Entspricht einer zweistelligen Zeichenfolge, die mit einem beginnt und mit einer beliebigen Ausnahme von \n
endet.|
OR Operator
a|b
bedeutet, dass entweder a
oder b
abgeglichen werden können.red|white|orange
entspricht genau einer der Farben.^
NICHT Operator
[^0-9]
darf keine Zahl enthalten[^aA]
Zeichen kann nicht in Kleinbuchstaben geschrieben werden a
oder in Großbuchstaben geschrieben werden A
\
Maskiert das folgende Sonderzeichen (überschreibt das obige Verhalten)
\.
, \\
, \(
, \?
, \$
, \^
Verankerungsmuster:
^
Die Übereinstimmung muss am Anfang der Zeichenfolge erfolgen
^a
Das erste Zeichen muss ein Kleinbuchstabe sein a
^[0-9]
Das erste Zeichen muss eine Zahl sein.$
Übereinstimmung muss am Ende der Zeichenfolge auftreten
a$
Das letzte Zeichen muss ein Kleinbuchstabe sein a
Rangfolgetabelle:
Order Name Representation
1 Parentheses ( )
2 Multipliers ? + * {m,n} {m, n}?
3 Sequence & Anchors abc ^ $
4 Alternation |
Vordefinierte Zeichenabkürzungen:
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
Beispiel 1 : Als Makro ausführen
Das folgende Beispielmakro überprüft den Wert in Zelle A1
, um festzustellen, ob die ersten 1 oder 2 Zeichen Ziffern sind. In diesem Fall werden sie entfernt und der Rest der Zeichenfolge wird angezeigt. Wenn nicht, wird ein Feld angezeigt, das Sie darüber informiert, dass keine Übereinstimmung gefunden wurde. Die Werte der Zelle A1
von 12abc
geben abc
zurück, der Wert von 1abc
gibt abc
zurück, der Wert von abc123
gibt "Nicht übereinstimmend" zurück, weil Die Ziffern befanden sich nicht am Anfang der Zeichenfolge.
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
Beispiel 2 : Als In-Cell-Funktion ausführen
Dieses Beispiel ist dasselbe wie Beispiel 1, ist jedoch so eingerichtet, dass es als In-Cell-Funktion ausgeführt wird. Ändern Sie dazu den Code wie folgt:
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
Platzieren Sie Ihre Zeichenfolgen ("12abc") in Zelle A1
. Geben Sie diese Formel =simpleCellRegex(A1)
in die Zelle B1
ein und das Ergebnis ist "abc".
Beispiel 3 : Durchschleifbereich
Dieses Beispiel ist dasselbe wie Beispiel 1, durchläuft jedoch eine Reihe von Zellen.
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
Beispiel 4 : Aufteilen verschiedener Muster
In diesem Beispiel wird ein Bereich (A1
, A2
& A3
) durchlaufen und nach einer Zeichenfolge gesucht, die mit drei Ziffern beginnt, gefolgt von einem einzelnen Buchstaben und anschließend vier Ziffern. Die Ausgabe teilt die Musterübereinstimmungen mithilfe von ()
in benachbarte Zellen auf. $1
repräsentiert das erste Muster, das innerhalb des ersten Satzes von ()
übereinstimmt.
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
Ergebnisse:
Zusätzliche Musterbeispiele
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
Um reguläre Ausdrücke direkt in Excel-Formeln zu verwenden, kann die folgende benutzerdefinierte Funktion (UDF) hilfreich sein. Die Funktionalität für reguläre Ausdrücke wird mehr oder weniger direkt als Excel-Funktion verfügbar gemacht.
Es werden 2-3 Parameter benötigt.
$0
, $1
, $2
und so weiter enthalten. $0
ist die gesamte Übereinstimmung, $1
und höher entsprechen den jeweiligen Übereinstimmungsgruppen im regulären Ausdruck. Der Standardwert ist $0
.E-Mail-Adresse extrahieren:
=regex("Peter Gordon: [email protected], 47", "\[email protected]\w+\.\w+")
=regex("Peter Gordon: [email protected], 47", "\[email protected]\w+\.\w+", "$0")
Ergebnisse in: [email protected]
Mehrere Teilstrings extrahieren:
=regex("Peter Gordon: [email protected], 47", "^(.+): (.+), (\d+)$", "E-Mail: $2, Name: $1")
Ergebnisse in: E-Mail: [email protected], Name: Peter Gordon
So zerlegen Sie eine kombinierte Zeichenfolge in einer einzelnen Zelle in ihre Komponenten in mehreren Zellen:
=regex("Peter Gordon: [email protected], 47", "^(.+): (.+), (\d+)$", "$" & 1)
=regex("Peter Gordon: [email protected], 47", "^(.+): (.+), (\d+)$", "$" & 2)
Ergebnisse in: Peter Gordon
[email protected]
...
Um diese UDF zu verwenden, gehen Sie wie folgt vor (ungefähr basierend auf diese Microsoft-Seite . Sie haben dort einige gute zusätzliche Informationen!):
ALT+F11
drücken, um den Microsoft Visual Basic für Applikationen Editor zu öffnen.Klicken Sie auf Modul einfügen. Wenn Sie Ihrem Modul einen anderen Namen geben, vergewissern Sie sich, dass das Modul nicht den gleichen Namen wie die unten stehende UDF hat (z. B. bewirkt die Benennung des Moduls Regex
und der Funktion regex
# NAME! Fehler).
Geben Sie im großen Textfenster in der Mitte Folgendes ein:
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
Speichern und schließen Sie das Fenster Microsoft Visual Basic für Applikationen Editor.
Erweitern auf patszim 's Antwort für die in einem Ansturm.
fügen Sie den folgenden Code hinzu:
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
Das Regex-Muster wird in eine der Zellen gestellt und mit absoluter Referenzierung versehen. Die Funktion ist an die Arbeitsmappe gebunden, in der sie erstellt wurde.
Wenn die Verwendung in verschiedenen Arbeitsmappen erforderlich ist, speichern Sie die Funktion in Personal.XLSB .
Hier ist mein Versuch:
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
Ich musste dies als Zellenfunktion verwenden (wie SUM
oder VLOOKUP
) und stellte fest, dass es einfach war:
Erstellen Sie die folgende Funktion entweder in der Arbeitsmappe oder in einem eigenen Modul:
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
Dann können Sie in Zelle mit =REGPLACE(B1, "(\w) (\d+)", "$1$2")
(Beispiel: "A 243" bis "A243")
Hier ist eine regex_subst()
Funktion. Beispiele:
=regex_subst("watermellon", "[aeiou]", "")
---> wtrmlln
=regex_subst("watermellon", "[^aeiou]", "")
---> aeeo
Hier ist der vereinfachte Code (für mich sowieso einfacher). Ich konnte nicht herausfinden, wie ich ein geeignetes Ausgabemuster mit den oben genannten Methoden erstellen kann, um wie in meinen Beispielen zu funktionieren:
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
Ich möchte keine Referenzbibliothek aktivieren müssen, da meine Skripte portierbar sein müssen. Die Zeile Dim foo As New VBScript_RegExp_55.RegExp
verursachte User Defined Type Not Defined
Fehler, aber ich fand eine Lösung, die für mich funktionierte.
Sie möchten einfach eine Beispielzeichenfolge in die Zelle A1
einfügen und dann Ihr strPattern
testen. Sobald dies funktioniert, stellen Sie rng
wie gewünscht ein.
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