Reguläre Ausdrücke verwenden

By , 20. April 2009

Mal angenommen Sie wollen Eingaben in einem ungebundenem Formular auf ihre Richtigkeit prüfen. Eine geläufige Vorgehensweise wäre z.B. den Feldinhalt gegen Null zu prüfen, oder die Länge auf eine bestimmte Mindestanzahl an Zeichen. Das ist alles aber ziemlich ungenau und lässt meist großen Spielraum bei der Falscheingabe.

Eine alternative Möglichkeit ist es sogenannte Reguläre Ausdrücke (Regexp, regular expressions) zu verwenden, welche in vielen Entwicklungssprachen und vorallem in Scriptsprachen wie PHP bekannt sind.

Reguläre Ausdrücke bestehen aus einem Muster, das in Begrenzer eingeschlossen wird, sowie aus verschiedenen Schaltern, den Modifizierern. In VB/VBA wurde allerdings auf die Begrenzer verzichtet, und die Modifizierer sind aus der Zeichenkette – welche dem regulären Ausdruck entspricht – ausgegliedert als Eigenschaft des entsprechenden Objektes.

Wagen wir mal einen Blick über den Tellerand hinüber zur Scriptsprache PHP und definieren wir mal einen regulären Ausdruck:

$pattern = „/^([A-Z]{1,2})?(-| )?([0-9]{5})$/“;

In diesem Muster sind so gut wie alle Techniken von regulären Ausdrücken enthalten, dass nicht kundige schon ins grübeln kommen. Mir ging das nicht anderst. Im obigen Beispiel wollen eine Eingabe einer Postleitzahl auf Ihre Richtigkeit überprüfen. Die Postleitzahl könnte z.B. so aussehen: D-80807 oder D80807 oder nur 80807.

Zerlegen wir nun die einzelnen Elemente des regulären Ausdruckes. Abgesehen von den Begrenzern, das sind die beiden Schrägstriche zwischen denen das Muster sitzt, und möglichen Schaltern, ist der Reguläre Ausdruck identisch mit dem der in VB/VBA Verwendung finden könnte, aber der Reihe nach.

Zuerst soll geprüft werden ob 1 oder 2 Großbuchstaben am Anfang stehen.
Das ist dieser Teil: ^([A-Z]{1,2})?
Das Zirkumflex (^) bedeutet dass der zu untersuchende Ausdruck mit dem nachfolgendem Teil anfangen muss. Soll z.B. ein Feldwert mit x beginnen, dann wäre das folgende Muster richtig: ^x.

Danach sollen mindestens 1 und maximal 2 Großbuchstaben kommen. Das wird durch [A-Z] ausgedrückt, die Begrenzung auf 1 oder 2 macht dieser Ausdruck: {1,2}. Wollte man statt dessen genau 1 Großbuchstaben haben, würde man {1} schreiben. Beides, Buchstaben und Begrenzer, sind in runden Klammern eingefasst. Diese dienen lediglich dazu Elemente zu gruppieren.

Zum Schluss folgt das Fragezeichen, dieses steht für 0 oder genau 1 vorstehendes Zeichen/Gruppierung. Dies bedeutet dass ein Ausdruck sowohl mit 1 oder 2 Großbuchstaben beginnen kann, oder dass gar kein Großbuchstabe am Anfang steht.

Danach soll ein Bindestrich bzw. ein Leerzeichen kommen, oder eben nichts davon. Wir setzen zuerst wieder eine runde Klammer und danach ein Fragezeichen. ()? Dies bedeutet dass der Klammerausdruck 0x oder genau 1x vorkommen darf. In der Klammer sollte dann ein senkrechter Strich oder ein Leerzeichen stehen. Diese Auswahl zwischen 2 Zeichen wird mit dem senkrechten Strich gekennzeichnet, also (-| )?

Zum Schluss sollen dann genau 5 Zahlen kommen. Wir setzen wieder eine runde Klammer, darin dann zuerst die Zahlenmenge [0-9] danach die Bestimmung der Anzahl Zeichen mittels {5}. Und da der Ausdruck damit auch aufhören soll, wird am Schluss ein $-Zeichen eingefügt. Dieser Teil sieht also wie folgt aus:
([0-9]{5})$

Nachfolgend nun noch eine Auflistung der einzelnen Elemente von Regulären Ausdrücken:

Zeichen Bedeutung
^ steht für Anfang einer Zeichenkette
$ steht für das Ende einer Zeichenkette
| kennzeichnet Alternativen, z.B. (1|2|3)
() runde Klammern gruppieren bestimmte Bereiche
[] eckige Klammern kennzeichnen Characterklassen, also z.B. [a-zA-Z]
{} geschweifte Klammern, geben die Anzahl der Wiederholungen an.
. jedes beliebige Zeichen außer Zeilenumbruch
* Quantifizierer, steht für 0 oder mehr Zeichen
+ Quantifizierer, steht für 1 oder mehr Zeichen
? Quantifizierer, steht für 0 oder genau 1 Zeichen
{n} Quantifizierer, steht für genau n Zeichen
{n,} Quantifizierer, steht für mindestens n Zeichen
{n,m} Quantifizierer, steht für min. n und max. m Zeichen

So, genug der grauen Theorie, jetzt wenden wir diesen Regulären Ausdruck in VBA mal auf verschiedene Testausdrücke an. Es gibt 2 Arten dies zu tun. Entweder man setzt einen Verweis auf die Microsoft VBSript Regular Expressions 5.5, oder verwendet late Binding ohne Verweis. Und letzteren zeige ich nachfolgend:

Public Sub RegexpTest()
    Dim oRegExp As Object, oMatch As Object
    Dim strText As String

    Set oRegExp = CreateObject("vbscript.regexp")
    oRegExp.Global = False
    oRegExp.IgnoreCase = True
    oRegExp.MultiLine = False
    oRegExp.pattern = "^([A-Z]{1,2})?(-| )?([0-9]{5})$"

    strText = "D-80807"
    Set oMatch = oRegExp.Execute(strText)
    If oMatch.Count = 0 Then
        MsgBox "Ihre Eingabe ist nicht korrekt!"
    Else
        'Ausgabe zu Testzwecken
        MsgBox "Eingabe korrekt!"
    End If
    Set oRegExp = Nothing
    Set oMatch = Nothing
End Sub

Zuerst werden 2 Objekte oRegExp und oMatch deklariert, das LateBinding findet sich in der Zeile:
Set oRegExp = CreateObject(„vbscript.regexp“)
wieder. Wo in PHP noch die Modifizierer i, s oder m als Schalter Verwendung fanden, sind diese hier Eigenschaften des Objektes oRegExp. Das Muster wird ebenfalls als Eigenschaft übergeben, und danach auf das Objekt oRegexp die Methode Execute mit dem Ausdruck strText angewendet und das Ergebnis im Objekt oMatch gespeichert. Ist dessen Eigenschaft Count = 0 so wurde der Ausdruck nicht gefunden.

Probiert es aus und variiert mal den Test-Ausdruck. Z.B. D-8080 wird da nicht mehr als korrekt durchgehen.
Im Netz finden sich viele fertige Muster für die verschiedensten Ausdrücke wie z.B. EMail, Handy-Nummer etc. diese könnt ihr analog obigem Beispiel ganz einfach verwenden.

AV 2009

Nachtrag
Anbei einige Musterstrings für reguläre Ausdrücke.

Email-Adresse:pattern = "^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$"

Webseite:pattern = "^http://(www.|[a-zA-Z].)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,})(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\;\?\'\\\+&%\$#\=~_\-]+))*$"

IP-Adresse:pattern = "^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$"

Mobilfunknummer: (auch formatiert möglich)pattern = "^([+][ ]?[1-9][0-9][ ]?[-]?[ ]?|[(]?[0][ ]?)[0-9]{3,4}[-)/ ]?[ ]?[1-9][-0-9 ]{6,16}$"

7 Responses to “Reguläre Ausdrücke verwenden”

  1. vanthy sagt:

    Vielen Dank für das Tutorial, hat mir sehr geholfen!

  2. Andreas Vogt sagt:

    Hallo Rainer,
    du hast natürlich vollkommen recht, danke.

  3. Rainer Warth sagt:

    Auch ich würde mich gerne für diesen schöne blog Beitrag bedanken.
    Mir viel auf, dass in dem Kasten „Zeichenerklärung“ folgendes steht:
    {} geschweifte Klammern
    Sollte es nicht eher folgender Text sein ?
    {} geschweifte Klammern geben die Wiederhohlungen an.

  4. I’m so glad I found this site…Keep up the good work

  5. Andreas Vogt sagt:

    Danke für die Info.
    Aber das war schon gewollt. Es werden 4×3 Zahlen gesucht die duch Punkt getrennt sind.

    Um eine gültige IP zu finden ist der Pattern wesentlich komplexer:
    „^(([01]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.){3}([01]?[0-9]{1,2}|2[0-4][0-9]|25[0- 5])$“

    Gruß Andreas

  6. mueller sagt:

    Das Pattern für die IP-Adresse ist so aber nicht ganz korrekt. Es würde nämlich auch 999.999.999.999 matchen, was definitiv keine IP-Adresse ist.

Leave a Reply

You must be logged in to post a comment.

OfficeFolders theme by Themocracy