This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
vba:tutorials:regexpreplacewithfunction [26.11.2014 15:14:10] yaslaw |
vba:tutorials:regexpreplacewithfunction [19.10.2015 15:59:17] (current) yaslaw |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== [VBA][Code Pattern] RegExp Replace mit Funktion ====== | ====== [VBA][Code Pattern] RegExp Replace mit Funktion ====== | ||
- | Naja, der Titel ist ev. irreführend. Mir kahm aber kein besserer in den Sinn. | + | //Ein Tutorial zum Thema, wie man eine %%RegExp Replace%% in einer Schleife anwenden kann.// |
- | \\ Es geht um folgendes: Mittels eines %%RegExp%% ermittle ich Teilstrings. Diese sollen über eine Funktion verändert werden und dann im String den Originalteilstring ersetzen. | + | |
+ | Naja, der Titel ist ev. irreführend. Mir kahm aber kein besserer in den Sinn. Es geht um folgendes: Mittels eines %%RegExp%% ermittle ich Teilstrings. Diese sollen über eine Funktion verändert werden und dann im String den Originalteilstring ersetzen. | ||
+ | |||
+ | ===== Beispielsaufgabe ===== | ||
Ein kleines Beispiel: den folgende String | Ein kleines Beispiel: den folgende String | ||
- | \\ ''Bären und Hüner gehören nicht in Ämter'' | + | <code>Bären und Hühner gehören nicht in Ämter</code> |
- | \\ Jetzt will ich alle äöü und ÜÖÜ in Unicode setzen | + | Jetzt will ich alle äöü und ÜÖÜ in Unicode setzen |
- | \\ ''B\u00E4ren und H\u00FCner geh\u00F6ren nicht in \u00C4mter'' | + | <code>B\u00E4ren und H\u00FChner geh\u00F6ren nicht in \u00C4mter</code> |
Dazu habe ich mal die Funktion [[vba:cast:char2unicode]], welche mir einen einzelnen Char nach Unicode wandelt. | Dazu habe ich mal die Funktion [[vba:cast:char2unicode]], welche mir einen einzelnen Char nach Unicode wandelt. | ||
+ | ===== Umsetzungen ===== | ||
Mit %%RegExp.replace()%% kann ich bekanntlich keine User-Funktion ausführen. Darum löse ich das meistens wie folgt. | Mit %%RegExp.replace()%% kann ich bekanntlich keine User-Funktion ausführen. Darum löse ich das meistens wie folgt. | ||
> Für die Ausgabe der Resultate verwendete ich die Funktion [[vba:functions:print_r:index]] | > Für die Ausgabe der Resultate verwendete ich die Funktion [[vba:functions:print_r:index]] | ||
+ | ==== Konzept ==== | ||
+ | Ich erstelle ein %%RegExp%%-Objekt, das genau nur ein Treffer zurückgibt (global=off). Mit einer Schleife teste ich auf den String, ob %%RegExp%% noch einen Treffer hat. | ||
+ | |||
+ | Jeder Treffer wird ausgelesen. Mittels einer UDF (User Defined Function) kann man mit dem gefundenen String oder Submatches etwas machen | ||
+ | |||
+ | Anschliessend nutze ich der %%RegExp%%.replace() um den Teilstring im Original durch den Neuen zu ersetzen | ||
+ | |||
+ | Das ganez wiederholen bis keine Treffer mehr da sind | ||
+ | |||
+ | ==== Einschränkung ==== | ||
+ | Es funktioniert natürlich nicht, wenn der neue String wieder dem Pattern entspricht. Wenn ich also bei %%IgnoreCase%% ''A'' durch ''a'' ersetzen will, landet das ganze in einer Endlosschleife. | ||
+ | |||
==== Version 1) Funktion mit detailiertem Aufbau ==== | ==== Version 1) Funktion mit detailiertem Aufbau ==== | ||
=== Beispielsfunktion replUmlaute() mit detailiertem Aufbau === | === Beispielsfunktion replUmlaute() mit detailiertem Aufbau === | ||
Die folgende Umsetzung beinhaltet eigentlich bereits die ganze Logik. Zum besseren Verständnis sind noch alle Schritte einzel auugeführt. Die Erklärung ist im Code mit drin. | Die folgende Umsetzung beinhaltet eigentlich bereits die ganze Logik. Zum besseren Verständnis sind noch alle Schritte einzel auugeführt. Die Erklärung ist im Code mit drin. | ||
<code vb>Public Function replUmlaute(ByVal iString As String) As String | <code vb>Public Function replUmlaute(ByVal iString As String) As String | ||
- | Static rx As regExp 'Das RegExp als Statisch definieren, damit es nicht bei jedem AUfruf initialisiert werden muss | + | 'Das RegExp als Statisch definieren, damit es nicht bei jedem Aufruf initialisiert werden muss |
+ | Static rx As regExp | ||
Dim mc As MatchCollection | Dim mc As MatchCollection | ||
Dim m As match | Dim m As match | ||
Line 27: | Line 43: | ||
rx.pattern = "([äöü])" | rx.pattern = "([äöü])" | ||
rx.IgnoreCase = True | rx.IgnoreCase = True | ||
- | 'Die folgedne Zeile müsste ich eigentlich nicht setzen. | + | 'Die folgende Zeile müsste ich eigentlich nicht setzen. |
'Aber es ist Wichtig, dass Global nicht auf True ist. | 'Aber es ist Wichtig, dass Global nicht auf True ist. | ||
rx.Global = False | rx.Global = False | ||
Line 45: | Line 61: | ||
unicode = char2unicode(sm(0)) | unicode = char2unicode(sm(0)) | ||
'und den ersten Treffer mittels RegExp ersetzen | 'und den ersten Treffer mittels RegExp ersetzen | ||
+ | 'Dank global=off gibts nur den einen Treffer zu ersetzen | ||
replUmlaute = rx.Replace(replUmlaute, unicode) | replUmlaute = rx.Replace(replUmlaute, unicode) | ||
Loop | Loop | ||
End Function</code> | End Function</code> | ||
=== Test der Funktion === | === Test der Funktion === | ||
- | <code vb>d replUmlaute("Bären und Hüner gehören nicht in Ämter") | + | <code vb>d replUmlaute("Bären und Hühner gehören nicht in Ämter") |
- | <String> 'B\u00E4ren und H\u00FCner geh\u00F6ren nicht in \u00C4mter'</code> | + | <String> 'B\u00E4ren und H\u00FChner geh\u00F6ren nicht in \u00C4mter'</code> |
==== Version 2) Kompakte Version ==== | ==== Version 2) Kompakte Version ==== | ||
- | In dieser Version verzichte ich darauf, alle Schritte einzeln durchzugehen. Auch das ertellen des %%RegExp%% überlasse ich der Funktion [[vba:cast:cregexp#Abgespeckte Version|[VBA] cRegExp() Abgespeckte Version]]. Dann sieht der Code noch so aus. | + | In dieser Version verzichte ich darauf, alle Schritte einzeln durchzugehen. Auch das ertellen des %%RegExp%% überlasse ich der Funktion [[vba:cast:cregexp#abgespeckte_version_crx|[VBA] cRegExp() Abgespeckte Version]]. Dann sieht der Code noch so aus. |
Ja, der erste ist besser lesbar. Wenn an aber ein Pattern immer wieder verwendet, erkennt man es beim lesen vom Code sofort. | Ja, der erste ist besser lesbar. Wenn an aber ein Pattern immer wieder verwendet, erkennt man es beim lesen vom Code sofort. | ||
Line 67: | Line 84: | ||
=== Test der Funktion replUmlaute() === | === Test der Funktion replUmlaute() === | ||
- | <code vb>d replUmlaute("Bären und Hüner gehören nicht in Ämter") | + | <code vb>d replUmlaute("Bären und Hühner gehören nicht in Ämter") |
- | <String> 'B\u00E4ren und H\u00FCner geh\u00F6ren nicht in \u00C4mter'</code> | + | <String> 'B\u00E4ren und H\u00FChner geh\u00F6ren nicht in \u00C4mter'</code> |
=== Beispielsfunktion replUmlauteBack() kompakt === | === Beispielsfunktion replUmlauteBack() kompakt === | ||
Line 82: | Line 99: | ||
=== Test der Funktion replUmlauteBack() === | === Test der Funktion replUmlauteBack() === | ||
- | <code vb>d replUmlauteBack("B\u00E4ren und H\u00FCner geh\u00F6ren nicht in \u00C4mter") | + | <code vb>d replUmlauteBack("B\u00E4ren und H\u00FChner geh\u00F6ren nicht in \u00C4mter") |
- | <String> 'Bären und Hüner gehören nicht in Ämter'</code> | + | <String> 'Bären und Hühner gehören nicht in Ämter'</code> |
===== Beipiele in Action ===== | ===== Beipiele in Action ===== |