Hi,
ich habe mir heute durch Zufall mal die Typbibliotheken von VBScript angesehen und dabei auf etwas interessantes gestoßen: damit lässt sich relativ einfach mit RegularExpressions verwenden. Die Frage wie selbiges funktioniert kommt ja immer häufiger auf, deswegen möchte ich hier das ganz kurz erklären.
Nachdem ich angefangen habe das Tutorial zu schreiben, ist mir folgende Quelle über den Weg gelaufen, die das gleiche auch erklärt:
SwissDelphiCenter.ch. Dort ist das ganze auf englisch erklärt. Hier möchte ich das jedoch auf deutsch mit eigenen Erfahrungen darstellen.
1. Installation
Als erstes muss die aktuelle Version der Windows Script heruntergeladen werden (derzeit 5.6). Bei
Microsoft gibt es den Download. Wenn man seine Anwendung mit den Regularexpressions weitergibt muss man diese Script Engine weitergeben. Hierbei reicht die Datei
vbscript.dll. Diese muss aber auch auf dem Zielsystem mit
regsvr32 registriert werden (ist halt die
DLL für die Typenbibliothek):
Nachdem das Paket heruntergeladen und installiert wurde, muss Windows neugestartet werden, danach können wir in Delphi die Typenbibliothek importieren. Das geht über den (von
XML 
) bekannten Weg:
Zitat:
Projekt -> Typbibliothek importieren... -> Microsoft VBScript Regular Expressions 5.5 (Version 5.5)
(Mir ist unerklärlich, wie dort 5.5 stehen kann, obwohl ich gerade Version 5.6 heruntergeladen habe)
Der Dateiname ist leider etwas lang, aber wichtig zu merken:
VBScript_RegExp_55_TLB.pas
Soweit ist das nun einsatzbereit. Als Nächstes können wir eine kleine Beispielanwendung durchgehen.
2. Beispiel
Das Beispiel habe ich 'rausgegriffen, weil es das einzige ist, wo ich wirklich sinnvoll Regular Expressions verwende. Es geht dabei darum die BBCodes in einer Seite (das was hier auch im Forum für die Formatierung verwendet wird) einfach herauszufiltern und durch
HTML-Tags zu ersetzen. Ich habe es mir hier in einem kleinen Projekt nicht als OnClick-Ereignis, wie ich es hier zeige verwendet, sondern so, wie man es auch in PHP findet als Funktionen wie
preg_match_all. Da ich allerdings gerne die Verwendung zeigen will, mache ich das hier einfach, wie die meisten es machen würden einfach in ein Button-OnClick-Ereignis.
Ich habe auf meinem Formular ein SynEdit (kann natürlich auch ein Memo sein; ein RichEdit wäre wegen den RTF-Formatierungen nicht zu empfehlen), aus dem ich den Quelltext beziehe. Als zweites habe ich eine beliebige Stringlist, die ich dann als
HTML-Datei speichern könnte. Am Ende der Methode passiert absichtlich nichts damit, weil jeder selber gucken sollte, was er damit anstellt.

Ein wenig Nachdenken soll ja auch nicht schaden. *g*
Als erstes sollte die
Unit VBScript_RegExp_55_TLB in die
uses aufgenommen werden.
Delphi-Quellcode:
procedure TfrmMain.btnParseClick(Sender: TObject);
{ Leider sind die Typennamen in der DLL etwas unglücklich gewählt (z.B. fehlendes T, wie es Delphistandard ist). Deswegen sind die Variablennamen auch etwas komisch gewählt. }
var
RegExpHandler: RegExp;
Matches: MatchCollection;
ExportList: TStringList;
PatternString, ReplaceString, ResultString:
string;
begin
ExportList := TStringList.Create;
RegExpHandler := CoRegExp.Create;
RegExpHandler.Global := true;
// es sollen wirklich alle Vorkommnisse ersetzt werden
RegExpHandler.MultiLine := true;
// Wenn ein String umgebrochen wird, soll das trotzdem akzeptiert werden
RegExpHandler.IgnoreCase := true;
// Groß- und Kleinschreibung ignorieren
// zu suchender Ausdruck
PatternString := '
\[b\](*.?)\[\/b\]';
RegExpHandler.Pattern := PatternString;
// zu ersetzender Ausdruck
ReplaceString := '
[b]$1[/b]';
// Regulären Ausdruck ausführen
ResultString := RegExpHandler.Replace(SynHTMLEdit.Lines.CommaText, ReplaceString);
// Überarbeiteter String der Stringliste hinzufügen
ExportList.CommaText := ResultString;
end;
3. Vorteil von regulären Ausdrücken
Sicher stellt man sich die Frage, warum man die relativ schwierige Welt der regulären Ausdrücke lernen soll, da Delphi ja auch einige praktische Funktionen bereit hat. Ich kann jetzt nur für mich persönlich sprechen, aber ich halte die regulären Ausdrücke zwar für relativ kompliziert (das genannte Beispiel ist ein halt ein Trivial-Fall), aber auch für sehr nützlich, wenn ich bestimmte Strings, die variieren können such will. Angenommen ich suche nach BBCodes, die noch einen Parameter bekommen können (z.B.
[url=...]), dann muss ich mit den normalen Stringfunktionen relativ viele if-Abfragen machen und es kann schnell passieren, dass man den Überblick verliert.
Diese paar Zeilen finde ich dann doch wesentlich komfortabler. Aber das ist meine persönliche Ansicht.

Wenn mir jemand plausibel erklärt, wie ich obiges in weniger Zeilen und genauso guter Übersicht mit den Stringfunktionen von Delphi machen kann, dann akzeptiere ich das. Aber ich kann gerne mal ein Beispiel raussuchen, womit man sich mit den Stringfunktionen zu Tode quälen wird (wenn selbst das einfacher gut: gut.

).
4. Bemerkungen
Das Problem ist, dass zum Einen die
DLL weitergegeben werden muss, allerdings eben diese von manchen Virenscannern und Firewalls geblockt wird, weil damit auch Viren ausgeführt werden können. Darum gibt es auch sinnvolle Alternativen wie zum Beispiel das
RegExp-Studio. Meine Anleitung für die VBScript Engine sollte nur als Alternativbeispiel gelten.
Interessant und etwas schwieriger wird es, wenn man nur mit Hilfe von regulären Ausdrücken suchen will. Dann werden die Typen [i]MatchCollection[i],
ISubMatches und
Match wichtig. In den nächsten Tagen werde ich sicherlich auch was dazu schreiben, jetzt muss ich aber noch ein wenig arbeiten.
Über Feedback würde ich mich freuen.
Chris