version=2.1.0 vdate=01.12.2014 fname=cast_cregexp.bas ns=%NAMESPACE% fpath=/vba/cast ====== [VBA] cRegExp(), cRx() ====== //Schnelles erstellen eines %%RegExp%%-Obektes mit erweiterten Pattern (Patterns erweitert um die Settings von %%RegExp%%).// ==Version %%version%% (%%vdate%%)== Diese Funktion erstellt aus einem Pattern direkt ein %%RegExp%%-Objekt. Das erspart im Code immer ein Mehrzeiler zu generieren um ein %%RegExp%%-Objekt mit allen Settings zu bekommen. \\ Zudem kann man für einfache Anwendungen direkt damit weiterarbeiten ohne das Objekt in eine Variable zu schreiben {{:vba:cast:cast_cregexp.bas|Download %%fname%% (V-%%version%%)}} ===== Definitionen ===== RegExp = cRegExp(pattern [,flags]) RegExp = cRegExp(pattern inkl. flags) Public Function cRegExp( _ ByVal iPattern As String, _ Optional ByVal iFlag As rxpFlagsEnum = rxnone _ ) As Object ***iPattern** Ein normaler Regulärer Ausdruck oder einer in der PHP-Schreibweise mit Delemiter und Modifiers ***iFlag** Kombination der Flags(analog den Modifiers) um das %%RegExp%% zu steuern. ==== Enumeratoren ==== === rxFlagsEnum === '/** ' * Wird für die rx_ Funktionen verwendet ' * Setzte die Flags für das RegExp Object ' */ Public Enum rxFlagsEnum rxnone = 2 ^ 0 'Value 1 rxglobal = 2 ^ 1 'Value 2 rxIgnorCase = 2 ^ 2 'Value 4 rxMultiline = 2 ^ 3 'Value 8 End Enum Setzte die Flags für das RegExp Object. Für das genaue Verhalten bitte die VB-Doku zur RegExp Klasse studieren ***rxNone** Alle Parameter werden auf False gesetzt. Wird vor allem zum überschreiben des Standards gebraucht. ***rxGlobal** Setzt Global(([[http://msdn.microsoft.com/en-us/library/tdte5kwf(v=vs.84).aspx|Global Property auf MSDN]])) auf True ***rxIgnorCase** Setzt IgnorCase(([[http://msdn.microsoft.com/en-us/library/wy1d4bz3(v=vs.84).aspx|IgnorCase Property auf MSDN]])) auf True ***rxMultiline** Setzt Multiline auf True ==== Pattern inkl. Modifiers ==== Die Suchstrings können als Reguläre Ausdrücke daherkommen. Dazu müssen sie wie in PHP für preg_match() mittels Delemiter und Modifiers formatiert werden. [Delemiter][Regulärer Ausdruck][Delemiter][Modifiers] === Delemiter === Als Delemiter können die folgenden Zeichen verwendet werden @&!/~#=| === Modifiers === Es gibt 3 Modifier.Genau soviele wie die %%RegExp%%-Klasse Properties hat. Die Grosskleinschreibung wird nicht berücksichtig. Ebensowenig die Reihenfolge. ***i** %%IgnoreCase%% ***g** Global ***m** Multiline ===== Beispiele ===== > Für die Ausgabe der Resultate verwendete ich die Funktion [[:vba:functions:print_r :]]. ==== Beispiele mit Paramatern ==== In den folgenden Beispielen wird als erstes Argument der Nackte Pattern mitgegeben und als 2te die Parameter 'Ohne weitere Paramters d cRegExp("ABC ([a-k]*)") ( [Pattern] => 'ABC ([a-k]*)' [Global] => False [IgnoreCase] => False [Multiline] => False ) 'Mit IgnoreCase d cRegExp("ABC ([a-k]*)", rxpIgnorCase) ( [Pattern] => 'ABC ([a-k]*)' [Global] => False [IgnoreCase] => True [Multiline] => False ) 'Mit IgnoreCase und Multiline d cRegExp("ABC ([a-k]*)", rxpIgnorCase + rxpMultiline) ( [Pattern] => 'ABC ([a-k]*)' [Global] => False [IgnoreCase] => True [Multiline] => True ) ==== Beispiele mit Patterns inkl. den Parametern ==== 'Ohne Parameters und / als Delemiter d cRegExp("/ABC ([a-k]*)/") ( [Pattern] => 'ABC ([a-k]*)' [Global] => False [IgnoreCase] => False [Multiline] => False ) 'Mit IgnoreCase und @ asl Delemiter d cRegExp("@ABC ([a-k]*)@i") ( [Pattern] => 'ABC ([a-k]*)' [Global] => False [IgnoreCase] => True [Multiline] => False ) 'IgnoreCase und Multiline und ! als Delemiter. Im Pattern selber kommt auch ein ! vor, wird korrekterweise nicht als Delemiter erkannt d cRegExp("!ABC! ([a-k]*)!im") ( [Pattern] => 'ABC! ([a-k]*)' [Global] => False [IgnoreCase] => True [Multiline] => True ) === Sinnvolle Anwendung === Diese 'Alles in einem String'-Art macht so natürlich wenig Sinn. Aber in gewissen Funktionen kann es durchaus lukrativ sein. So habe ich cRegExp() erfolgreich in die Funktion [[vba:functions:strreplace]] eingebaut. Dort wäre es nicht möglich mit den erweiterten Parametern zu arbeiten. 'Ersetze alle test.com-Domainen durch gmail.com und alle gmail.com durch test.com. 'Dabei soll die Grosskleinschreibweise ignoriert werden d strReplace("test@Test.com,hans@test.com,jonas@gmail.com", "/([\w_\.-]+)@test.com/i", "$1@gmail.com", "/([\w_\.-]+)@gmail.com/i", "$1@test.com") 'test@gmail.com,hans@gmail.com,jonas@test.com' ==== Beispiel innerhalb einer Methode ==== Public Sub testCRegExp() Dim mc As Object: Set mc = cRegExp("\(([^\)]+)\)", rxpGlobal).execute("(123)(456)") Dim m As Object: For Each m In mc Debug.Print m.value Next m End Sub ===== Code ===== ==== Originalcode ==== {{:vba:cast:cast_cregexp.bas|Download %%fname%% (V-%%version%%)}} ==== Abgespeckte Version cRx() ==== Häufig kopiere ich die folgenden Zeilen als Library in ein Modul oder Klasse um sie Selbständig zu machen. Siehe auch [[#sinnvolle anwendung]]. \\ Die folgende Version ist analog zu vielen JQuery-Scripten die min-Version. Sprich, es ist dasseleb wie die Haubtversion, jedoch so kompakt dass es nicht mehr einfach lesbar ist. Dafür bläht es den Code nicht so stark auf, wenn man die Funktion in ein weiteres Modul packt. '/** ' * Dies ist die Minimalversion von cRegExp ' * http://wiki.yaslaw.info/dokuwiki/doku.php/vba/cast/cregexp#abgespeckte_version ' * mögliche Delemiter: @&!/~#=\| ' * mögliche Modifiers: g (Global), i (IgnoreCode, m (Mulitline) ' * ' * @example myRx = cRx("/([a]{2,})/i") 'Finde alle folgen von a. Flag:IgnoreCase ' * @version 2.1.0 (01.12.2014) ' * @param String Pattern mit Delimiter und Modifier analog zu PHP ' * @return Object RegExp-Object ' */ Private Function cRx(ByVal iPattern As String) As Object Static rxP As Object: Set cRx = CreateObject("VBScript.RegExp") If rxP Is Nothing Then: Set rxP = CreateObject("VBScript.RegExp"): rxP.pattern = "^([@&!/~#=\|])?(.*)\1(?:([Ii])|([Gg])|([Mm]))*$" Dim sm As Object: Set sm = rxP.Execute(iPattern)(0).subMatches cRx.pattern = sm(1): cRx.IgnoreCase = Not isEmpty(sm(2)): cRx.Global = Not isEmpty(sm(3)): cRx.Multiline = Not isEmpty(sm(4)) End Function