{"id":55001616,"date":"2026-10-01T00:00:00","date_gmt":"2026-09-06T19:29:25","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1616"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Regulaere_Ausdruecke_in_VBA_Teil_1_Basics","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/","title":{"rendered":"Regul&auml;re Ausdr&uuml;cke in VBA, Teil 1: Basics"},"content":{"rendered":"<p><b>Wer in VBA pr&uuml;fen will, ob eine Eingabe eine g&uuml;ltige E-Mail-Adresse ist, baut sich meist eine Schleife mit &#8222;InStr&#8220;, &#8222;Mid&#8220; und &#8222;Left&#8220; zusammen &#8211; und k&auml;mpft dann mit Sonderf&auml;llen. Mit regul&auml;ren Ausdr&uuml;cken erledigt eine einzige Zeile dieselbe Aufgabe. Das n&ouml;tige Werkzeug geh&ouml;rt seit vielen Jahren zu Windows, allerdings &uuml;ber eine Bibliothek, die Microsoft gerade abk&uuml;ndigt. Gleichzeitig hat das VBA-Team reagiert und die Funktionalit&auml;t fest eingebaut. Dieser erste Teil unserer Reihe zeigt, wie Sie das Objekt einbinden, welche Klassen es mitbringt und wie die Mustersprache funktioniert. Der zweite Teil liefert dann fertige Rezepte f&uuml;r den Alltag.<\/b><\/p>\n<h2>Wozu das Ganze?<\/h2>\n<p>Ein regul&auml;rer Ausdruck ist ein Suchmuster, das mit einer eigenen kleinen Sprache beschreibt, wie ein gesuchter Text aufgebaut ist.<\/p>\n<p>Statt Zeichen f&uuml;r Zeichen zu pr&uuml;fen, formulieren wir also die Regel &#8211; und die Suchmaschine k&uuml;mmert sich um den Rest. Ein paar Aufgaben, die sich damit auf eine Zeile eindampfen lassen:<\/p>\n<ul>\n<li>Pr&uuml;fen, ob eine Eingabe dem Format einer E-Mail-Adresse entspricht<\/li>\n<li>Alle Zahlen aus einem Freitextfeld herausl&ouml;sen<\/li>\n<li>HTML-Tags aus einem kopierten Text entfernen<\/li>\n<li>Platzhalter in einer Textvorlage durch Werte ersetzen<\/li>\n<li>Mehrfache Leerzeichen und Zeilenumbr&uuml;che zu einem einzigen zusammenfassen<\/li>\n<li>Pr&uuml;fen, ob eine Telefonnummer nur erlaubte Zeichen enth&auml;lt<\/li>\n<\/ul>\n<p>Der Einstieg lohnt sich also. Und weil das Ergebnis jeweils eine kleine Funktion ist, die Sie auch direkt in Abfragen einsetzen k&ouml;nnen, w&auml;chst mit jedem Muster Ihre eigene Werkzeugsammlung.<\/p>\n<h2>Das RegExp-Objekt einbinden<\/h2>\n<p>Bis vor Kurzem gab es genau einen Weg: das Objekt <b>VBScript.RegExp<\/b> aus der Bibliothek <b>Microsoft VBScript Regular Expressions 5.5<\/b>, die hinter der Datei <b>vbscript.dll<\/b> steckt. Sie binden es entweder &uuml;ber einen Verweis ein (fr&uuml;he Bindung) oder erzeugen es zur Laufzeit &uuml;ber <b>CreateObject<\/b> (sp&auml;te Bindung). Den Verweis finden Sie im VBA-Editor unter <b>Extras\/Verweise<\/b> &#8211; Bild 1 zeigt den entsprechenden Eintrag.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_05\/pic_1616_001.png\" alt=\"Der Verweis auf die VBScript-Bibliothek im Verweise-Dialog\" width=\"499,5589\" height=\"393,8207\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Der Verweis auf die VBScript-Bibliothek im Verweise-Dialog<\/span><\/b><\/p>\n<p>Genau diese Bibliothek verschwindet aber. Microsoft hat die Abk&uuml;ndigung von VBScript im Oktober 2023 angek&uuml;ndigt und im Mai 2024 einen Zeitplan in drei Phasen nachgeschoben. In der ersten Phase, die bis 2026 oder 2027 l&auml;uft, bleibt VBScript als optionales Feature vorinstalliert und aktiviert. In der zweiten Phase wird es standardm&auml;&szlig;ig deaktiviert, und in einer dritten Phase ohne festen Termin verschwindet es vollst&auml;ndig aus Windows. Sp&auml;testens dann k&ouml;nnen Anwendungen nicht mehr darauf vertrauen, dass die bisherige VBScript-RegExp-Bibliothek unter Windows verf&uuml;gbar ist.<\/p>\n<p>Die gute Nachricht: Das VBA-Team hat vorgesorgt. <b>Ab Office-Version 2508 (Build 19127.20154) sind die RegExp-Klassen fest in VBA eingebaut<\/b> und stehen ohne jeden Verweis zur Verf&uuml;gung. Sie k&ouml;nnen also einfach schreiben:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>objRegEx<span style=\"color:blue;\"> As <\/span>RegExp\r\n<span style=\"color:blue;\">Set<\/span> objRegEx = <span style=\"color:blue;\">New<\/span> RegExp<\/pre>\n<p>Ob Ihre Installation schon so weit ist, pr&uuml;fen Sie am schnellsten mit einem Test im Direktbereich. Kompiliert die folgende Zeile ohne Fehler, sind die eingebauten Klassen vorhanden:<\/p>\n<pre><span style=\"color:blue;\">Debug.Print<\/span> TypeName(<span style=\"color:blue;\">New<\/span> RegExp)\r\nRegExp<\/pre>\n<p>Alternativ werfen Sie einen Blick auf die Datei <b>vbe7.dll<\/b> im Verzeichnis der gemeinsam genutzten Office-Komponenten. Ab der Dateiversion 7.1.11. sind die Klassen enthalten. Sollte die Office-Version stimmen, die Klassen aber trotzdem fehlen, hilft erfahrungsgem&auml;&szlig; eine Schnellreparatur der Office-Installation.<\/p>\n<p>F&uuml;r Anwendungen, die Sie ausliefern, ergibt sich daraus eine klare Empfehlung: <b>Verwenden Sie die sp&auml;te Bindung.<\/b> Der Aufruf mit <b>CreateObject<\/b> funktioniert sowohl auf &auml;lteren Systemen, auf denen VBScript noch aktiv ist, als auch auf neuen Office-Versionen ohne VBScript &#8211; er greift dort automatisch auf die eingebauten Klassen zu. Die fr&uuml;he Bindung an die neu in VBA integrierte Klasse funktioniert dagegen erst ab Office-Version 2508. Auf &auml;lteren Versionen setzt sie weiterhin einen Verweis auf die VBScript-Bibliothek voraus.<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>objRegEx<span style=\"color:blue;\"> As Object<\/span>\r\n<span style=\"color:blue;\">Set<\/span> objRegEx = CreateObject(\"VBScript.RegExp\")<\/pre>\n<p>Eine Entwarnung noch, weil die Frage regelm&auml;&szlig;ig aufkommt: Die Objekte <b>Scripting.Dictionary<\/b> und <b>Scripting.FileSystemObject<\/b> sind von der Abk&uuml;ndigung <b>nicht<\/b> betroffen. Sie stammen aus der Bibliothek <b>scrrun.dll<\/b> und bleiben erhalten &#8211; das hat der zust&auml;ndige Produktmanager auf Nachfrage ausdr&uuml;cklich best&auml;tigt.<\/p>\n<h2>Vier Klassen, mehr braucht es nicht<\/h2>\n<p>Das Objektmodell ist erfreulich &uuml;bersichtlich.<\/p>\n<p>Es besteht aus genau vier Klassen:<\/p>\n<ul>\n<li><b>RegExp<\/b> ist das Suchobjekt. Hier legen Sie das Muster und die Optionen fest und starten die Suche.<\/li>\n<li><b>MatchCollection<\/b> nimmt alle gefundenen Treffer auf. Die Auflistung ist nullbasiert und kennt die Eigenschaft <b>Count<\/b>.<\/li>\n<li><b>Match<\/b> steht f&uuml;r einen einzelnen Treffer mit den Eigenschaften <b>Value<\/b>, <b>FirstIndex<\/b> und <b>Length<\/b>.<\/li>\n<li><b>SubMatches<\/b> enth&auml;lt die Inhalte der Klammergruppen innerhalb eines Treffers &#8211; ebenfalls nullbasiert.<\/li>\n<\/ul>\n<p>Bei der sp&auml;ten Bindung deklarieren Sie alle diese Variablen schlicht als <b>Object<\/b>. Sie verlieren dadurch zwar IntelliSense, gewinnen aber die Lauff&auml;higkeit auf allen Systemen.<\/p>\n<h2>Die vier Eigenschaften des RegExp-Objekts<\/h2>\n<p>Bevor wir suchen, stellen wir das Objekt ein. Es gibt genau vier Eigenschaften, und drei davon sind Schalter:<\/p>\n<ul>\n<li><b>Pattern<\/b> nimmt den regul&auml;ren Ausdruck als Zeichenkette auf.<\/li>\n<li><b>Global<\/b> bestimmt, ob nach dem ersten Treffer weitergesucht wird. <b>Der Standardwert ist False<\/b> &#8211; das ist die h&auml;ufigste Stolperfalle &uuml;berhaupt, denn ein <b>Replace<\/b> ersetzt dann nur das erste Vorkommen.<\/li>\n<li><b>IgnoreCase<\/b> schaltet die Unterscheidung von Gro&szlig;- und Kleinschreibung ab. Auch hier lautet der Standardwert False, Suchen erfolgen also zun&auml;chst gro&szlig;-\/kleinschreibungsempfindlich.<\/li>\n<li><b>Multiline<\/b> sorgt daf&uuml;r, dass die Anker f&uuml;r Zeilenanfang und Zeilenende nicht nur am Anfang und Ende des gesamten Textes greifen, sondern an jedem Zeilenumbruch.<\/li>\n<\/ul>\n<p>Damit haben wir alles beisammen, um die erste Suche zu starten.<\/p>\n<h2>Die Methode Test: Passt das Muster?<\/h2>\n<p>Am einfachsten ist <b>Test<\/b>. Die Methode liefert schlicht <b>True<\/b> oder <b>False<\/b> zur&uuml;ck, je nachdem, ob das Muster irgendwo im &uuml;bergebenen Text vorkommt.<\/p>\n<p>Das folgende Listing pr&uuml;ft, ob eine Zeichenkette ausschlie&szlig;lich eine f&uuml;nfstellige Postleitzahl enth&auml;lt.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TestPostleitzahl()\r\n    <span style=\"color:blue;\">Dim <\/span>objRegEx<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">Set<\/span> objRegEx = CreateObject(\"VBScript.RegExp\")\r\n    objRegEx.Pattern = \"^\\d{5}$\"\r\n    <span style=\"color:blue;\">Debug.Print<\/span> objRegEx.Test(\"47051\")\r\n    <span style=\"color:blue;\">Debug.Print<\/span> objRegEx.Test(\"4705\")\r\n    <span style=\"color:blue;\">Debug.Print<\/span> objRegEx.Test(\"47051 Duisburg\")\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Ausgabe im Direktbereich sieht so aus:<\/p>\n<pre>Wahr\r\nFalsch\r\nFalsch<\/pre>\n<p>Der dritte Aufruf zeigt, wozu die beiden Anker gut sind. Das Dach am Anfang verlangt, dass der Treffer am Textanfang beginnt, das Dollarzeichen am Ende, dass er am Textende aufh&ouml;rt.<\/p>\n<p>Ohne diese beiden Zeichen w&uuml;rde auch die dritte Zeile ein <b>Wahr<\/b> liefern, weil die f&uuml;nf Ziffern ja irgendwo im Text vorkommen. Das ist ein beliebter Fehler bei Pr&uuml;ffunktionen: Wer verifizieren will, dass ein Feld <b>ausschlie&szlig;lich<\/b> aus dem gew&uuml;nschten Muster besteht, muss beide Anker setzen.<\/p>\n<h2>Die Methode Execute: Was wurde gefunden?<\/h2>\n<p>Interessanter wird es, wenn wir wissen wollen, <b>was<\/b> gefunden wurde. Dazu dient <b>Execute<\/b>. Die Methode liefert eine <b>MatchCollection<\/b> zur&uuml;ck, durch die wir schlicht mit <b>For Each<\/b> laufen. Listing 1 sucht alle Zahlen in einem Freitext.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>ZahlenFinden()\r\n    <span style=\"color:blue;\">Dim <\/span>objRegEx<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>objTreffer<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>objMatch<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strText<span style=\"color:blue;\"> As String<\/span>\r\n    strText = \"Bestellung 4711 vom 12.03.2026 &uuml;ber 3 Stueck zu je 19,90 Euro\"\r\n    <span style=\"color:blue;\">Set<\/span> objRegEx = CreateObject(\"VBScript.RegExp\")\r\n    objRegEx.Pattern = \"\\d+\"\r\n    objRegEx.Global = <span style=\"color:blue;\">True<\/span>\r\n    <span style=\"color:blue;\">Set<\/span> objTreffer = objRegEx.Execute(strText)\r\n    <span style=\"color:blue;\">Debug.Print<\/span> \"Treffer: \" & objTreffer.Count\r\n    For Each objMatch In objTreffer\r\n        <span style=\"color:blue;\">Debug.Print<\/span> objMatch.FirstIndex + 1, objMatch.Length, objMatch.Value\r\n    <span style=\"color:blue;\">Next<\/span> objMatch\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Alle Zahlen eines Textes ermitteln<\/span><\/b><\/p>\n<p>Der Direktbereich meldet:<\/p>\n<pre>Treffer: 7\r\n12            4             4711\r\n22            2             12\r\n25            2             03\r\n28            4             2026\r\n39            1             3\r\n50            2             19\r\n53            2             90<\/pre>\n<p>Zwei Beobachtungen. Erstens war hier <b>Global = True<\/b> entscheidend &#8211; ohne diese Zeile h&auml;tten wir genau einen Treffer erhalten. Zweitens rechnen wir bei <b>FirstIndex<\/b> eine Eins hinzu.<\/p>\n<p>Die Eigenschaft ist n&auml;mlich nullbasiert, w&auml;hrend <b>Mid<\/b> und <b>Left<\/b> in VBA bei Eins zu z&auml;hlen beginnen. Wer diesen Versatz &uuml;bersieht, schneidet konsequent ein Zeichen zu fr&uuml;h aus. Dass das Datum in drei Teile zerf&auml;llt, liegt nat&uuml;rlich am Muster: Wir haben <b>Ziffernfolge<\/b> gesagt, nicht <b>Datum<\/b>. Wie man das sauber formuliert, sehen wir gleich.<\/p>\n<h2>Klammergruppen und SubMatches<\/h2>\n<p>Eine Klammergruppe hat in einem regul&auml;ren Ausdruck zwei Aufgaben. Sie fassen einen Teilausdruck zusammen, und sie merken sich, was an dieser Stelle gefunden wurde. Genau diese gemerkten Teile landen in der Auflistung <b>SubMatches<\/b>. Damit zerlegen wir ein Datum in seine Bestandteile (siehe Listing 2).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>DatumZerlegen()\r\n    <span style=\"color:blue;\">Dim <\/span>objRegEx<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>objTreffer<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>objMatch<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">Set<\/span> objRegEx = CreateObject(\"VBScript.RegExp\")\r\n    objRegEx.Pattern = \"(\\d{1,2})\\.(\\d{1,2})\\.(\\d{4})\"\r\n    objRegEx.Global = <span style=\"color:blue;\">True<\/span>\r\n    <span style=\"color:blue;\">Set<\/span> objTreffer = objRegEx.Execute( _\r\n        \"Termine: 12.03.2026 und 5.4.2026\")\r\n    For Each objMatch In objTreffer\r\n        <span style=\"color:blue;\">Debug.Print<\/span> \"Gesamt: \" & objMatch.Value\r\n        <span style=\"color:blue;\">Debug.Print<\/span> \"  Tag:   \" & objMatch.SubMatches(0)\r\n        <span style=\"color:blue;\">Debug.Print<\/span> \"  Monat: \" & objMatch.SubMatches(1)\r\n        <span style=\"color:blue;\">Debug.Print<\/span> \"  Jahr:  \" & objMatch.SubMatches(2)\r\n    <span style=\"color:blue;\">Next<\/span> objMatch\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Zerlegen eines Datums in Tag, Monat und Jahr<\/span><\/b><\/p>\n<p>Beachten Sie die maskierten Punkte im Muster. Ein unmaskierter Punkt bedeutet n&auml;mlich <b>ein beliebiges Zeichen<\/b> &#8211; wir wollen hier aber wirklich einen Punkt sehen. Der umgekehrte Schr&auml;gstrich davor nimmt dem Punkt seine Sonderbedeutung. Das Ergebnis:<\/p>\n<pre>Gesamt: 12.03.2026\r\n  Tag:   12\r\n  Monat: 03\r\n  Jahr:  2026\r\nGesamt: 5.4.2026\r\n  Tag:   5\r\n  Monat: 4\r\n  Jahr:  2026<\/pre>\n<h2>Die Methode Replace<\/h2>\n<p>Die dritte Methode ersetzt gefundene Stellen durch einen neuen Text. Der Clou dabei: Im Ersatztext k&ouml;nnen Sie mit <b>$1<\/b> bis <b>$9<\/b> auf die Klammergruppen zugreifen und mit <b>$&#038;<\/b> auf den gesamten Treffer. Damit l&auml;sst sich ein deutsches Datum in einem Rutsch in das ISO-Format &uuml;berf&uuml;hren (siehe Listing 3).<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>DatumNachIso(ByVal strText<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>objRegEx<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">Set<\/span> objRegEx = CreateObject(\"VBScript.RegExp\")\r\n    objRegEx.Global = <span style=\"color:blue;\">True<\/span>\r\n    objRegEx.Pattern = \"\\b(\\d{2})\\.(\\d{2})\\.(\\d{4})\\b\"\r\n    DatumNachIso = objRegEx.<span style=\"color:blue;\">Replace<\/span>(strText, \"$3-$2-$1\")\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Datumsangaben in das ISO-Format umschreiben<\/span><\/b><\/p>\n<p>Der Aufruf <b>DatumNachIso(&#8222;Rechnung vom 12.03.2026&#8220;)<\/b> liefert <b>Rechnung vom 2026-03-12<\/b>. Die beiden Zeichenfolgen \\b an den Enden stehen jeweils f&uuml;r eine Wortgrenze und verhindern, dass mitten aus einer l&auml;ngeren Ziffernfolge heraus ersetzt wird.<\/p>\n<h2>Die Mustersprache im &Uuml;berblick<\/h2>\n<p>Nun zur Sprache selbst. Sie besteht aus einer &uuml;berschaubaren Zahl von Bausteinen.<\/p>\n<p>Zun&auml;chst die Zeichenklassen, also Platzhalter f&uuml;r eine Gruppe von Zeichen:<\/p>\n<ul>\n<li><b>.<\/b> steht f&uuml;r ein beliebiges Zeichen au&szlig;er dem Zeilenumbruch.<\/li>\n<li><b>\\d<\/b> trifft eine Ziffer, <b>\\D<\/b> alles au&szlig;er einer Ziffer.<\/li>\n<li><b>\\w<\/b> trifft ein Wortzeichen, <b>\\W<\/b> das Gegenteil.<\/li>\n<li><b>\\s<\/b> trifft ein Leerzeichen im weiteren Sinne, also auch Tabulator und Umbruch.<\/li>\n<li><b>[abc]<\/b> trifft genau eines der aufgef&uuml;hrten Zeichen, <b>[a-z]<\/b> einen Bereich und <b>[^abc]<\/b> alles au&szlig;er den genannten Zeichen.<\/li>\n<\/ul>\n<p>Hier lauert eine Falle, die deutschsprachige Entwickler regelm&auml;&szlig;ig trifft: <b>\\w umfasst nur die Zeichen A bis Z, a bis z, die Ziffern und den Unterstrich.<\/b> Umlaute und das scharfe S geh&ouml;ren nicht dazu. Ein Muster wie <b>^\\w+$<\/b> weist den Namen <b>M&uuml;ller<\/b> also zur&uuml;ck. Wer deutsche Namen pr&uuml;fen will, muss die Zeichen ausdr&uuml;cklich mit aufnehmen:<\/p>\n<pre>objRegEx.Pattern = \"^[A-Za-z&Auml;&Ouml;&Uuml;&auml;&ouml;&uuml;&szlig;\\- ]+$\"<\/pre>\n<p>Der Bindestrich ist mit einem umgekehrten Schr&auml;gstrich maskiert, damit er nicht als Bereichsangabe interpretiert wird.<\/p>\n<p>Als N&auml;chstes die Quantoren, die angeben, wie oft der vorangehende Baustein vorkommen darf:<\/p>\n<ul>\n<li><b>?<\/b> bedeutet h&ouml;chstens einmal, also einmal oder gar nicht.<\/li>\n<li>Der Stern bedeutet beliebig oft, auch gar nicht.<\/li>\n<li><b>+<\/b> bedeutet mindestens einmal.<\/li>\n<li><b>{3}<\/b> bedeutet genau dreimal, <b>{2,4}<\/b> zwei- bis viermal und <b>{2,}<\/b> mindestens zweimal.<\/li>\n<\/ul>\n<p>Dazu kommen die Anker und Gruppierungen:<\/p>\n<ul>\n<li><b>^<\/b> markiert den Textanfang, <b>$<\/b> das Textende.<\/li>\n<li><b>\\b<\/b> markiert eine Wortgrenze.<\/li>\n<li><b>(&#8230;)<\/b> bildet eine Gruppe, deren Inhalt in <b>SubMatches<\/b> landet.<\/li>\n<li><b>(?:&#8230;)<\/b> bildet eine Gruppe, ohne sich den Inhalt zu merken &#8211; das ist schneller und h&auml;lt die Nummerierung der &uuml;brigen Gruppen &uuml;bersichtlich.<\/li>\n<li><b>|<\/b> trennt Alternativen, etwa <b>(Herr|Frau)<\/b>.<\/li>\n<\/ul>\n<h2>Gierig oder gen&uuml;gsam?<\/h2>\n<p>Ein Punkt, der Anf&auml;nger zuverl&auml;ssig zur Verzweiflung bringt: Quantoren arbeiten standardm&auml;&szlig;ig <b>gierig<\/b>, greifen sich also so viel Text wie irgend m&ouml;glich.<\/p>\n<p>Wer aus einem HTML-Schnipsel den ersten Tag herausl&ouml;sen will und dazu das Muster <b><.+><\/b> verwendet, bekommt nicht den ersten Tag, sondern alles vom ersten &ouml;ffnenden bis zum letzten schlie&szlig;enden spitzen Klammerzeichen.<\/p>\n<p>Abhilfe schafft ein Fragezeichen hinter dem Quantor. Es schaltet ihn auf gen&uuml;gsam um, sodass er sich mit dem k&uuml;rzestm&ouml;glichen Treffer zufriedengibt. Das folgende Listing zeigt den Unterschied:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>GierigOderNicht()\r\n    <span style=\"color:blue;\">Dim <\/span>objRegEx<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strHtml<span style=\"color:blue;\"> As String<\/span>\r\n    strHtml = \"&lt;b&gt;Hallo&lt;\/b&gt; &lt;i&gt;Welt&lt;\/i&gt;\"\r\n    <span style=\"color:blue;\">Set<\/span> objRegEx = CreateObject(\"VBScript.RegExp\")\r\n    objRegEx.Pattern = \"&lt;.+&gt;\"\r\n    <span style=\"color:blue;\">Debug.Print<\/span> objRegEx.Execute(strHtml)(0).Value\r\n    objRegEx.Pattern = \"&lt;.+?&gt;\"\r\n    <span style=\"color:blue;\">Debug.Print<\/span> objRegEx.Execute(strHtml)(0).Value\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Ausgabe macht das Problem sofort sichtbar:<\/p>\n<pre>&lt;b&gt;Hallo&lt;\/b&gt; &lt;i&gt;Welt&lt;\/i&gt;\r\n&lt;b&gt;<\/pre>\n<p>Merken Sie sich als Faustregel: Wenn ein Punkt mit Quantor nicht m&ouml;glichst viel, sondern nur bis zur n&auml;chsten passenden Begrenzung erfassen soll, ben&ouml;tigen Sie in der Regel einen gen&uuml;gsamen Quantor wie .*? oder .+?.<\/p>\n<h2>Was diese Engine nicht kann<\/h2>\n<p>Die Suchmaschine hinter <b>RegExp<\/b> stammt aus der JScript-Welt und beherrscht deshalb einige Dinge nicht, die Sie aus Beispielen im Internet vielleicht kennen.<\/p>\n<p>Damit Sie nicht lange nach dem Fehler suchen, hier die wichtigsten L&uuml;cken:<\/p>\n<ul>\n<li><b>Kein R&uuml;ckw&auml;rtsblick.<\/b> Ausdr&uuml;cke der Form <b>(?<=...)<\/b> funktionieren nicht. Der Vorausblick mit <b>(?=&#8230;)<\/b> und <b>(?!&#8230;)<\/b> steht dagegen zur Verf&uuml;gung.<\/li>\n<li><b>Keine benannten Gruppen.<\/b> Sie m&uuml;ssen mit den Nummern in <b>SubMatches<\/b> arbeiten.<\/li>\n<li><b>Kein Schalter, der den Punkt auch auf Zeilenumbr&uuml;che anwendet.<\/b> Wenn Sie wirklich jedes Zeichen treffen wollen, schreiben Sie stattdessen <b>[\\s\\S]<\/b>.<\/li>\n<li><b>Keine Unicode-Eigenschaften.<\/b> Konstruktionen wie <b>\\p{L}<\/b> kennt die Engine nicht &#8211; weshalb wir Umlaute oben von Hand aufz&auml;hlen mussten.<\/li>\n<\/ul>\n<h2>Hilfsfunktionen f&uuml;r den Alltag<\/h2>\n<p>Alle bisherigen Beispiele brauchten vier bis f&uuml;nf Zeilen Vorbereitung, bevor &uuml;berhaupt gesucht wurde: Objekt erzeugen, Muster zuweisen, Optionen setzen, Suche starten.<\/p>\n<p>Das ist zum Kennenlernen richtig, im Alltag aber l&auml;stig.<\/p>\n<p>Deshalb kapseln wir die drei Methoden in drei Funktionen, die wir von nun an &uuml;berall verwenden &#8211; auch im zweiten Teil dieser Reihe.<\/p>\n<p>Alle drei folgen demselben Aufbau, damit man beim Wechsel zwischen ihnen nicht nachdenken muss:<\/p>\n<ul>\n<li>Der erste Parameter ist immer der zu durchsuchende Text, der zweite immer das Muster. Weitere Parameter sind optional.<\/li>\n<li>Keine der Funktionen l&ouml;st einen Fehler aus, wenn nichts gefunden wird. Sie liefern stattdessen <b>False<\/b> beziehungsweise einen Leerstring.<\/li>\n<li>Das RegExp-Objekt liegt in einer <b>Static<\/b>-Variablen und wird nur einmal erzeugt.<\/li>\n<li>Alle drei lassen sich unver&auml;ndert in Abfragen einsetzen.<\/li>\n<\/ul>\n<p>Der dritte Punkt verdient eine Erl&auml;uterung, weil er in der Praxis den Unterschied macht. Eine <b>Static<\/b>-Variable beh&auml;lt ihren Wert zwischen zwei Aufrufen der Funktion.<\/p>\n<p>Setzen Sie eine dieser Funktionen als Kriterium in einer Abfrage &uuml;ber zehntausend Datens&auml;tze ein, wird sie zehntausendmal aufgerufen &#8211; ohne <b>Static<\/b> w&uuml;rde dabei jedes Mal ein COM-Objekt erzeugt und gleich wieder verworfen. Mit <b>Static<\/b> geschieht das genau einmal. Die Zuweisung des Musters erfolgt weiterhin bei jedem Aufruf, ist aber vergleichsweise billig.<\/p>\n<h2>RegExTest: Passt das Muster?<\/h2>\n<p>Die erste Funktion namens <b>RegExTest <\/b>kapselt die Methode <b>Test<\/b> und liefert einen Wahrheitswert zur&uuml;ck (siehe Listing 4). Sie erwartet diese Parameter:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>RegExTest(ByVal strText<span style=\"color:blue;\"> As String<\/span>, ByVal strMuster<span style=\"color:blue;\"> As String<\/span>, <span style=\"color:blue;\">Optional<\/span> ByVal blnIgnoreCase<span style=\"color:blue;\"> As <\/span>_\r\n        Boolean = <span style=\"color:blue;\">True<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n    <span style=\"color:blue;\">Static <\/span>objRegEx<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">If <\/span>objRegEx Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n        <span style=\"color:blue;\">Set<\/span> objRegEx = CreateObject(\"VBScript.RegExp\")\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    objRegEx.Pattern = strMuster\r\n    objRegEx.IgnoreCase = blnIgnoreCase\r\n    objRegEx.Global = <span style=\"color:blue;\">False<\/span>\r\n    RegExTest = objRegEx.Test(strText)\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Kompakte Pr&uuml;ffunktion mit wiederverwendetem Objekt<\/span><\/b><\/p>\n<ul>\n<li><b>strText<\/b>: der zu pr&uuml;fende Text.<\/li>\n<li><b>strMuster<\/b>: der regul&auml;re Ausdruck.<\/li>\n<li><b>blnIgnoreCase<\/b>: optional, Vorgabewert <b>True<\/b>. Bei Pr&uuml;fungen ist die Schreibweise meist unerheblich &#8211; ob eine E-Mail-Adresse gro&szlig; oder klein geschrieben wird, &auml;ndert nichts an ihrer G&uuml;ltigkeit.<\/li>\n<\/ul>\n<p>Die Eigenschaft <b>Global<\/b> steht hier bewusst auf <b>False<\/b>. Uns interessiert ja nur, <b>ob<\/b> es einen Treffer gibt &#8211; die Suche darf also beim ersten abbrechen und muss den restlichen Text gar nicht mehr ansehen. Ein Beispielaufruf mitsamt Ausgabe:<\/p>\n<pre><span style=\"color:blue;\">Debug.Print<\/span> RegExTest(\"47051\", \"^\\d{5}$\")\r\n<span style=\"color:blue;\">Debug.Print<\/span> RegExTest(\"D-47051\", \"^\\d{5}$\")\r\n<span style=\"color:blue;\">Debug.Print<\/span> RegExTest(\"M&uuml;ller\", \"^[A-Z&Auml;&Ouml;&Uuml;][a-z&auml;&ouml;&uuml;&szlig;]+$\")\r\nWahr\r\nFalsch\r\nWahr<\/pre>\n<p>Der dritte Aufruf zeigt nebenbei, warum der Vorgabewert f&uuml;r <b>blnIgnoreCase<\/b> manchmal st&ouml;rt: Das Muster verlangt einen Gro&szlig;buchstaben am Anfang, aber weil wir die Gro&szlig;- und Kleinschreibung standardm&auml;&szlig;ig ignorieren, w&uuml;rde auch <b>m&uuml;ller<\/b> durchgehen.<\/p>\n<p>Wenn die Schreibweise Teil der Pr&uuml;fung ist, &uuml;bergeben Sie im dritten Parameter ausdr&uuml;cklich <b>False<\/b>.<\/p>\n<h2>RegExErsetzen: Suchen und ersetzen<\/h2>\n<p>Die zweite Funktion namens <b>RegExErsetzen <\/b>kapselt <b>Replace<\/b> (siehe Listing 5). Sie kommt mit drei Parametern aus:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>RegExErsetzen(ByVal strText<span style=\"color:blue;\"> As String<\/span>, ByVal strMuster<span style=\"color:blue;\"> As String<\/span>, ByVal strErsatz<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Static <\/span>objRegEx<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">If <\/span>objRegEx Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n        <span style=\"color:blue;\">Set<\/span> objRegEx = CreateObject(\"VBScript.RegExp\")\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    objRegEx.Pattern = strMuster\r\n    objRegEx.Global = <span style=\"color:blue;\">True<\/span>\r\n    objRegEx.IgnoreCase = <span style=\"color:blue;\">True<\/span>\r\n    RegExErsetzen = objRegEx.<span style=\"color:blue;\">Replace<\/span>(strText, strErsatz)\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Die Ersetzungsfunktion RegExErsetzen<\/span><\/b><\/p>\n<ul>\n<li><b>strText<\/b>: der zu bearbeitende Text.<\/li>\n<li><b>strMuster<\/b>: der regul&auml;re Ausdruck f&uuml;r die zu ersetzenden Stellen.<\/li>\n<li><b>strErsatz<\/b>: der Ersatztext. Hier d&uuml;rfen Sie mit <b>$1<\/b> bis <b>$9<\/b> auf die Klammergruppen zugreifen und mit <b>$&#038;<\/b> auf den gesamten Treffer.<\/li>\n<\/ul>\n<p>Anders als bei <b>RegExTest<\/b> steht <b>Global<\/b> hier fest auf <b>True<\/b>, denn beim Ersetzen will man in aller Regel alle Vorkommen erwischen und nicht nur das erste. Soll ausnahmsweise nur die erste Fundstelle ersetzt werden, k&ouml;nnen Sie <b>Global<\/b> &uuml;ber einen zus&auml;tzlichen optionalen Parameter steuerbar machen.<\/p>\n<pre><span style=\"color:blue;\">Debug.Print<\/span> RegExErsetzen(\"Zu    viel   Luft\", \"\\s+\", \" \")\r\n<span style=\"color:blue;\">Debug.Print<\/span> RegExErsetzen(\"Tel: 0203\/12345\", \"\\D\", \"\")\r\n<span style=\"color:blue;\">Debug.Print<\/span> RegExErsetzen(\"Meier, Anna\", \"(\\w+), (\\w+)\", \"$2 $1\")\r\nZu viel Luft\r\n020312345\r\nAnna Meier<\/pre>\n<p>Der dritte Aufruf zeigt die Klammergruppen im Einsatz: Das Muster merkt sich Nachname und Vorname, der Ersatztext setzt sie in umgekehrter Reihenfolge wieder zusammen.<\/p>\n<p>Damit drehen Sie eine ganze Namensspalte in einer einzigen Aktualisierungsabfrage um.<\/p>\n<h2>RegExGruppe: Den Treffer auslesen<\/h2>\n<p>Die dritte Funktion namens <b>RegExGruppe <\/b>ist diejenige, die Sie im Alltag am h&auml;ufigsten brauchen werden (siehe Listing 6).<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>RegExGruppe(ByVal strText<span style=\"color:blue;\"> As String<\/span>, ByVal strMuster<span style=\"color:blue;\"> As String<\/span>, <span style=\"color:blue;\">Optional<\/span> ByVal lngGruppe<span style=\"color:blue;\"> As Long<\/span> = 0) _\r\n       <span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Static <\/span>objRegEx<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>objTreffer<span style=\"color:blue;\"> As Object<\/span>\r\n    <span style=\"color:blue;\">If <\/span>objRegEx Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n        <span style=\"color:blue;\">Set<\/span> objRegEx = CreateObject(\"VBScript.RegExp\")\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    objRegEx.Pattern = strMuster\r\n    objRegEx.Global = <span style=\"color:blue;\">False<\/span>\r\n    objRegEx.IgnoreCase = <span style=\"color:blue;\">True<\/span>\r\n    <span style=\"color:blue;\">Set<\/span> objTreffer = objRegEx.Execute(strText)\r\n    ' Nichts gefunden: Leerstring zur&uuml;ckgeben\r\n    <span style=\"color:blue;\">If <\/span>objTreffer.Count = 0<span style=\"color:blue;\"> Then<\/span> <span style=\"color:blue;\">Exit Function<\/span>\r\n    <span style=\"color:blue;\">If <\/span>lngGruppe = 0<span style=\"color:blue;\"> Then<\/span>\r\n        RegExGruppe = objTreffer(0).Value\r\n    <span style=\"color:blue;\">Else<\/span>\r\n        RegExGruppe = _\r\n            objTreffer(0).SubMatches(lngGruppe - 1)\r\n    <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Auslesen eines Treffers oder einer Klammergruppe<\/span><\/b><\/p>\n<p>Sie kapselt <b>Execute<\/b> und liefert entweder den gesamten ersten Treffer oder den Inhalt einer bestimmten Klammergruppe:<\/p>\n<ul>\n<li><b>strText<\/b>: der zu durchsuchende Text.<\/li>\n<li><b>strMuster<\/b>: der regul&auml;re Ausdruck.<\/li>\n<li><b>lngGruppe<\/b>: optional, Vorgabewert <b>0<\/b>. Der Wert <b>0 <\/b>liefert den gesamten Treffer, <b>1 <\/b>die erste Klammergruppe, <b>2 <\/b>die zweite und so weiter.<\/li>\n<\/ul>\n<p>Zwei Entwurfsentscheidungen stecken darin. Erstens rechnen wir bei der Gruppe intern eine Eins ab, weil <b>SubMatches<\/b> nullbasiert ist.<\/p>\n<p>Nach au&szlig;en z&auml;hlen wir dagegen ab Eins &#8211; also genau so, wie es der Schreibweise <b>$1<\/b> im Ersatztext von <b>RegExErsetzen<\/b> entspricht. Das erspart beim Wechsel zwischen den beiden Funktionen einiges Nachdenken.<\/p>\n<p>Zweitens bricht die Funktion nicht ab, wenn nichts gefunden wird, sondern liefert einen Leerstring.<\/p>\n<p>Das ist Absicht: In einer Abfrage &uuml;ber tausende Datens&auml;tze w&uuml;rde ein Laufzeitfehler beim ersten unpassenden Datensatz die gesamte Auswertung stoppen. Wenn Sie zwischen <b>nicht gefunden<\/b> und <b>leer gefunden<\/b> unterscheiden m&uuml;ssen, pr&uuml;fen Sie zus&auml;tzlich mit <b>RegExTest<\/b>:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_RegExpGruppe()\r\n    <span style=\"color:blue;\">Dim <\/span>strZeile<span style=\"color:blue;\"> As String<\/span>\r\n    strZeile = \"Rechnung RE-2026-0815 vom 12.03.2026\"\r\n    \r\n    <span style=\"color:blue;\">Debug.Print<\/span> RegExGruppe(strZeile, _\r\n        \"RE-\\d{4}-\\d{4}\")\r\n    <span style=\"color:blue;\">Debug.Print<\/span> RegExGruppe(strZeile, _\r\n        \"RE-(\\d{4})-(\\d{4})\", 1)\r\n    <span style=\"color:blue;\">Debug.Print<\/span> RegExGruppe(strZeile, _\r\n        \"RE-(\\d{4})-(\\d{4})\", 2)\r\n    <span style=\"color:blue;\">Debug.Print<\/span> \"[\" & RegExGruppe(strZeile, _\r\n        \"XY-\\d+\") & \"]\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Das Resultat sieht wie folgt aus:<\/p>\n<pre>RE-2026-0815\r\n2026\r\n0815\r\n[]<\/pre>\n<h2>Einsatz in Abfragen<\/h2>\n<p>Weil alle drei Funktionen einen einfachen Datentyp zur&uuml;ckliefern, k&ouml;nnen Sie sie unmittelbar in Abfragen verwenden &#8211; sowohl in der Feldliste als auch in den Kriterien.<\/p>\n<p>Damit werden Auswertungen m&ouml;glich, die mit Bordmitteln nicht zu formulieren w&auml;ren:<\/p>\n<pre>SELECT Firma, Notiz,\r\n    RegExGruppe(Notiz, \"\\d{5}\") AS PLZ\r\nFROM tblKunden\r\nWHERE RegExTest(Notiz, \"\\d{5}\") = <span style=\"color:blue;\">True<\/span><\/pre>\n<p>Eine Voraussetzung gibt es allerdings: Die Funktionen m&uuml;ssen in einem <b>Standardmodul<\/b> stehen und als <b>Public<\/b> deklariert sein.<\/p>\n<p>In einem Klassen- oder Formularmodul findet Access sie nicht, und Sie erhalten die wenig hilfreiche Meldung, dass der Ausdruck eine undefinierte Funktion enth&auml;lt.<\/p>\n<p>Noch ein Hinweis: Wenn Sie Felder in Abfragen mit unseren Funktionen versehen, sichern Sie mit der Nz-Funktion ab, dass Null-Werte an die Funktion &uuml;bergeben werden. Dies w&uuml;rde anderenfalls einen Fehler ausl&ouml;sen.<\/p>\n<p>Alternativ k&ouml;nnen Sie auch direkt eine entsprechende Pr&uuml;fung in die Funktionen selbst integrieren.<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Mit vier Klassen, vier Eigenschaften und drei Methoden ist das Objektmodell schnell erlernt &#8211; die eigentliche Arbeit steckt in der Mustersprache.<\/p>\n<p>Wenn Sie sich die drei Hilfsfunktionen aus diesem Beitrag in ein Standardmodul kopieren, haben Sie die Grundlage f&uuml;r alles Weitere beisammen.<\/p>\n<p>Und noch einmal die wichtigste Empfehlung: Verwenden Sie in ausgelieferten Anwendungen die sp&auml;te Bindung &uuml;ber <b>CreateObject<\/b>. Sie ist die einzige Variante, die sowohl auf &auml;lteren Systemen mit aktivem VBScript als auch auf neuen Office-Versionen mit den eingebauten Klassen funktioniert &#8211; und damit die einzige, die den Umbau der kommenden Jahre unbeschadet &uuml;bersteht.<\/p>\n<p>Im zweiten Teil dieser Reihe verlassen wir die Theorie. Dort finden Sie fertige Muster f&uuml;r E-Mail-Adressen, IBANs, Telefonnummern und Postleitzahlen, dazu Funktionen zum Bereinigen von Texten, zum Extrahieren von Daten aus Freitextfeldern und zum Ersetzen von Platzhaltern in Textvorlagen.<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>RegulaereAusdruecke_Teil1.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/A8293012-75D2-40F6-811D-C46408959893\/aiu_1616.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wer in VBA pr&uuml;fen will, ob eine Eingabe eine g&uuml;ltige E-Mail-Adresse ist, baut sich meist eine Schleife mit &#8222;InStr&#8220;, &#8222;Mid&#8220; und &#8222;Left&#8220; zusammen &#8211; und k&auml;mpft dann mit Sonderf&auml;llen. Mit regul&auml;ren Ausdr&uuml;cken erledigt eine einzige Zeile dieselbe Aufgabe. Das n&ouml;tige Werkzeug geh&ouml;rt seit vielen Jahren zu Windows, allerdings &uuml;ber eine Bibliothek, die Microsoft gerade abk&uuml;ndigt. Gleichzeitig hat das VBA-Team reagiert und die Funktionalit&auml;t fest eingebaut. Dieser erste Teil unserer Reihe zeigt, wie Sie das Objekt einbinden, welche Klassen es mitbringt und wie die Mustersprache funktioniert. Der zweite Teil liefert dann fertige Rezepte f&uuml;r den Alltag.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662026,66052026,44000025],"tags":[],"class_list":["post-55001616","post","type-post","status-publish","format-standard","hentry","category-662026","category-66052026","category-VBA_und_Programmiertechniken"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v28.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Regul&auml;re Ausdr&uuml;cke in VBA, Teil 1: Basics - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Regul&auml;re Ausdr&uuml;cke in VBA, Teil 1: Basics\" \/>\n<meta property=\"og:description\" content=\"Wer in VBA pr&uuml;fen will, ob eine Eingabe eine g&uuml;ltige E-Mail-Adresse ist, baut sich meist eine Schleife mit &quot;InStr&quot;, &quot;Mid&quot; und &quot;Left&quot; zusammen - und k&auml;mpft dann mit Sonderf&auml;llen. Mit regul&auml;ren Ausdr&uuml;cken erledigt eine einzige Zeile dieselbe Aufgabe. Das n&ouml;tige Werkzeug geh&ouml;rt seit vielen Jahren zu Windows, allerdings &uuml;ber eine Bibliothek, die Microsoft gerade abk&uuml;ndigt. Gleichzeitig hat das VBA-Team reagiert und die Funktionalit&auml;t fest eingebaut. Dieser erste Teil unserer Reihe zeigt, wie Sie das Objekt einbinden, welche Klassen es mitbringt und wie die Mustersprache funktioniert. Der zweite Teil liefert dann fertige Rezepte f&uuml;r den Alltag.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-06T19:29:25+00:00\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"11\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Regul&auml;re Ausdr&uuml;cke in VBA, Teil 1: Basics\",\"datePublished\":\"2026-09-06T19:29:25+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\\\/\"},\"wordCount\":1881,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"articleSection\":[\"2026\",\"5\\\/2026\",\"VBA und Programmiertechniken\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\\\/\",\"name\":\"Regul&auml;re Ausdr&uuml;cke in VBA, Teil 1: Basics - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"datePublished\":\"2026-09-06T19:29:25+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Regul&auml;re Ausdr&uuml;cke in VBA, Teil 1: Basics\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Regul&auml;re Ausdr&uuml;cke in VBA, Teil 1: Basics - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/","og_locale":"de_DE","og_type":"article","og_title":"Regul&auml;re Ausdr&uuml;cke in VBA, Teil 1: Basics","og_description":"Wer in VBA pr&uuml;fen will, ob eine Eingabe eine g&uuml;ltige E-Mail-Adresse ist, baut sich meist eine Schleife mit \"InStr\", \"Mid\" und \"Left\" zusammen - und k&auml;mpft dann mit Sonderf&auml;llen. Mit regul&auml;ren Ausdr&uuml;cken erledigt eine einzige Zeile dieselbe Aufgabe. Das n&ouml;tige Werkzeug geh&ouml;rt seit vielen Jahren zu Windows, allerdings &uuml;ber eine Bibliothek, die Microsoft gerade abk&uuml;ndigt. Gleichzeitig hat das VBA-Team reagiert und die Funktionalit&auml;t fest eingebaut. Dieser erste Teil unserer Reihe zeigt, wie Sie das Objekt einbinden, welche Klassen es mitbringt und wie die Mustersprache funktioniert. Der zweite Teil liefert dann fertige Rezepte f&uuml;r den Alltag.","og_url":"https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/","og_site_name":"Access im Unternehmen","article_published_time":"2026-09-06T19:29:25+00:00","author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"11\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Regul&auml;re Ausdr&uuml;cke in VBA, Teil 1: Basics","datePublished":"2026-09-06T19:29:25+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/"},"wordCount":1881,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"articleSection":["2026","5\/2026","VBA und Programmiertechniken"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/","url":"https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/","name":"Regul&auml;re Ausdr&uuml;cke in VBA, Teil 1: Basics - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"datePublished":"2026-09-06T19:29:25+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Regulaere_Ausdruecke_in_VBA_Teil_1_Basics\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Regul&auml;re Ausdr&uuml;cke in VBA, Teil 1: Basics"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001616","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55001616"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001616\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001616"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001616"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001616"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}