Table of Contents

First PagePrevious PageBack to overviewNext PageLast Page

[VBA] rx_replace()

Ich kenne preg_replace() aus PHP. Diese Funktion wollte ich auch für VBA verfügbar haben. Hier nun meine Umsetzung davon. Natürlich ist die Funktionalität gegenüber dem Original aus PHP beschränkt, da RegExp aus VBScript hier einige Grenzen setzt.

Übersicht über alle rx-Funktionen: [VBA] RegExp Functions (RX-Functins)
Für die Ausgabe der Resultate verwendete ich die Funktion [VBA] print_r()

Definitionen

Public Function rx_replace( _
        ByVal iPattern As String, _
        ByVal iReplacement As String, _
        ByVal iSubject As String, _
        Optional ByVal iFlags As rxFlagsEnum = rxGlobal + rxIgnorCase _
) As String

Parameter-Liste

Enumeratoren

rxFlagsEnum

Setzte die Flags für das RegExp Object. Für das genaue Verhalten bitte die VB-Doku zur RegExp Klasse studieren

Anwendungsbeispiele

'Einfaches ersetzen
debug.print rx_replace("(\d+)\.(\d+)CHF", "$1 Franken und $2 Rappen", "Die Wurst kostet 6.50CHF")
Die Wurst kostet 6 Franken und 50 Rappen
 
debug.print rx_replace("(\d+\.\d{0,2})", "$1CHF", "Die Wurst kostet 6.50 und das Steak 3.50")
Die Wurst kostet 6.50CHF und das Steak 3.50CHF
 
debug.print rx_replace("(\d+\.\d{0,2})", "$1CHF", "Die Wurst kostet 6.50 und das Steak 3.50", rxNone)
Die Wurst kostet 6.50CHF und das Steak 3.50

Die Funktion kann auch in SQL angewendet werden. Doch Vorsicht, bei grösseren Datenmengen sollte man das rx-Objekt mitsamt seinen Settings in den Cache setzen, damit dieses nicht für jeden Datensatz neu erstellt werden muss

SELECT rx_replace("(\d+)\.(\d+)CHF", t.textfield) AS txt
FROM my_table

Die Flags müssen leider im SQL per Nummer übergeben werden. Für Global+IgnoreCase ist das 2+4

SELECT rx_replace("(\d+)\.(\d+)CHF", t.textfield, 2+4) AS txt
FROM my_table

Code

Der Enumerator rxFlagsEnum wird für alle rx-Funktionen verwendet.

'/**
' * 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
rx.bas
'/**
' * Copyright mpl by ERB software | http://wiki.yaslaw.info
' *
' * Die Idee hatte ich aus PHP. Ein Befehl für ein Regulärer Ausdruck-Replace ohne Mehrzeiler-Code
' * @example                new_string = rx_replace("([\W])", "_", "Hallo: Welt2!")
' * @param  String          Pattern analog RegExp
' * @param  String          Ersetzungsstring anaog zu RegExp.replace
' * @param  String          Der String der bearbeitet werden soll
' * @param  rxFlagsEnum     Eigenschaften von Regexp. Global, IgnoreCase und Multiline.
' *                         Die Eigenschaften können mit + kombiniert werden
' * @return String
' */
Public Function rx_replace( _
        ByVal iPattern As String, _
        ByVal iReplacement As String, _
        ByVal iSubject As String, _
        Optional ByVal iFlags As rxFlagsEnum = rxGlobal + rxIgnorCase _
) As String
'    Dim rx  As New regExp
    Dim rx As Object: Set rx = CreateObject("VBScript.RegExp")
 
    rx.Global = iFlags And rxGlobal
    rx.IgnoreCase = iFlags And rxIgnorCase
    rx.Multiline = iFlags And rxMultiline
 
    rx.Pattern = iPattern
 
    rx_replace = IIf(rx.test(iSubject), rx.Replace(iSubject, iReplacement), iSubject)
 
    Set rx = Nothing
End Function