User Tools

Site Tools


vba:functions:rx:rx_replace

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

  • iPattern Der Reguläre Ausdruck, mit dem gesucht wird
  • iReplacement Der Ersetzungsstring gemäss Definition zu RegExp.replace(). Die gefunden Submatches können mittels $Num angesprochen werden
  • iSubject Der Text der durchsucht werden soll
  • iFlags Eigenschaften von Regexp. Global, IgnoreCase und Multiline. Die Eigenschaften können mit + kombiniert werden

Enumeratoren

rxFlagsEnum

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 Global1) auf True
  • rxIgnorCase Setzt IgnorCase2) auf True
  • rxMultiline Setzt Multiline auf True

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
vba/functions/rx/rx_replace.txt · Last modified: 09.12.2013 09:39:54 (external edit)