version=1.2.0 vdate=12.11.2014 fname=udf_strreplace.bas ns=%NAMESPACE% fpath=/vba/functions ====== [VBA] strReplace() ====== //Diese Funktion ermöglicht es, mehrere Ersetzungen Gleichzeitig durchszuführen ohne dass sich diese gegenseitig in die Quere kommen.// ==Version %%version%% - %%vdate%%== {{%%fname%%|Download %%fname%% (V-%%version%%)}} Ein Beispiel im Direktfenster. Im Text 'Hans schlägt Fritz worauf Fritz zu Boden geht' will ich Hans durch Fritz ersetzen und Umgekehrt. Die klassische Art wäre mit 2 verschachtelten Replace. 'Erst Hans zu Fritz und dann Fritz zu Hans ? replace(replace("Hans schlägt Fritz worauf Fritz zu Boden geht", "Hans", "Fritz"), "Fritz", "Hans") Hans schlägt Hans worauf Hans zu Boden geht '2ter Versuch. Fritz zu Hans und dann Hans zu Fritz ? replace(replace("Hans schlägt Fritz worauf Fritz zu Boden geht", "Fritz", "Hans"), "Hans", "Fritz") Fritz schlägt Fritz worauf Fritz zu Boden geht Dasselbe mit strReplace(). Diesmal bekomme ich das gewünschte Resultat ? strReplace("Hans schlägt Fritz worauf Fritz zu Boden geht", "Hans", "Fritz", "Fritz", "Hans") Fritz schlägt Hans worauf Hans zu Boden geht Die Funktion lässt sich auf verschieden Arten anwenden. Mehr dazu unter den Beispielen. Die Suchbegriffe können auch Reguläre Ausdrücke sein und im Replace kann auf die Submatches zugegriffen werden. > Für die Ausgabe der Resultate verwendete ich die Funktion [[:vba:functions:print _r:]]. ===== Definition ===== string = strReplace(string, find1, replace1 [,find2, replace2...[,find#, replace#]]) string = strReplace(string, array(find1 [,find2...[find#]]), array(replace1 [,replace2...[,replace#]])) string = strReplace(string, dictionary1 [,dictionary2...[dictionary#]]) Public Function strReplace( _ ByVal iExpression As Variant, _ ParamArray iItems() As Variant _ ) As String ***iExpression** Der String, der bearbeitet werden soll ***iItems** %%ParamArray%% mit den verschiedenen Parameters. ==== Verschiedene Anwendungsmöglichkeiten ==== Es gibt 4 verschiedene Varianten. Die genaueren Beschreibung kann man bei der Funktion [[vba:cast:cdict]] nachschauen. cDict() wird intern verwendet um die Parametervielfallt abzudecken === 1) Abwechselnd Find/Replace === string = strReplace(string, find1, replace1 [,find2, replace2...[,find#, replace#]]) Die Suchbegriffe und die Ersetzungsstrings wechseln sich ab === 2) Kombination mit 2 Arrays === string = strReplace(string, array(find1 [,find2...[find#]]), array(replace1 [,replace2...[,replace#]])) Man übergibt 2 Arrays. Der Ersete beinhaltet alle Suchbegriffe, der 2te die Ersetzungsstrings === 3) Dictionary === string = strReplace(string, dictionary1 [,dictionary2...[dictionary#]]) Die Argumente werden als Dictionary übergeben. Der Key ist dabei jeweils der Suchbegriff, der Value der Ersetzungsstring === 4) Set-String === string = strReplace(string, string) Die Ersetzung können als [[vba:cast:cdict##ein_zuordnungsstring|Zuordnungsstring]] übergeben werden ==== String als Regulärer Ausdruck ==== 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 zum String als regExp=== Es sind dieselben Pattern wie auch für [[vba:cast:cregexp]] gültigkeit haben '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 ) ==== Beispiele zu strReplace ==== d strReplace("D123-X12; Bratpulver", "X12", "ID:12") 'D123-ID:12; Bratpulver' d strReplace("D123-X12; Bratpulver", "brat", "Koch", "pulver", "wasser") 'D123-X12; Kochwasser' 'Ganz normal mit 2 Suchbegriffen und 2 Ersetzungstexte d strReplace("P1 schlägt P2 worauf P2 zu boden geht", "P1", "P2", "P2", "P1") 'P2 schlägt P1 worauf P1 zu boden geht' 'Mit 2 Arrays: der erste Array beinhaltet die Suchbegriffe, der 2te die Ersetzungstexte d strReplace("D123-X12; Bratpulver", array("brat", "pulver"), array("Koch", "wasser")) 'D123-X12; Kochwasser' 'Als Regulärer. Der Erste mit IgnoreCase, der 2te Ohne d strReplace("D123-X12; Bratpulver (D123)", "/-x(\d+);/i", "-ID:$1;", "/^D(\d{1,3})/", "PREFIX:$1") 'PREFIX:123-ID:12; Bratpulver (D123)' 'Dasselbe wieder mit den 2 Arrays d strReplace("D123-X12; Bratpulver (D123)", array("/-x(\d+);/i", "/^D(\d{1,3})/"), array("-ID:$1;", "PREFIX:$1")) 'PREFIX:123-ID:12; Bratpulver (D123)' 'Wenn wir das IgnoreCase weglassen, findet er den String nicht mehr d strReplace("D123-X12; Bratpulver", "/-x(\d+);/", "-ID:$1;") 'D123-X12; Bratpulver' 'Wir haben im Such-Array mehr Einträge als im Ersetzungsarray: Es wird der letzte Ersetzungsstring für alle Weiteren verwendet 'Das Ausrufezeichen wird ebenfalls durch _ ersetzt, gneau wie alle Treffer des 2ten Patterns 'zudem sieht mann, dass der erste Suchbegriff vorrang hat, falls sich diese überschneiden. Der erste macht aus einem ö ein ue, der Zweite würde gerne aus einem ü ein _ machen d strReplace("Öl gibts bald nicht mehr! Dafür wasser", array( "ö", "/[äöü]/i", "!"), array("oe", "_")) 'oel gibts bald nicht mehr_ Daf_r wasser' 'und noch ein Versuch Mmittels Zuordnungsstring d strReplace("ABC", "'a'=>'b', 'b':'c'") 'bcC' Und ein Beispiel mit Dictionary als Argument Public Sub testStrReplace() Dim dict As New dictionary dict.add "A", "_a_" dict.add "/[a-z]/i", "{$1}" dict.add "C", "_c_" d strReplace("A B C 1", dict) End Sub '_a_ {$1} {$1} 1' ===== Code =====