VB 5/6-Tipp 0572: Reguläre Ausdrücke in VB benutzen
von Dominik Auras
Beschreibung
Dieser Tipp enthält zwei rle-algorithmen (komprimierung), einmal mit VB-Schleifen umgesetzt und einmal mit dem RegEx-Objekt in VB. Beide Verfahren werden per API genau abgestoppt um zu demonstrieren, das das RegEx-Objekt schneller ist. Zudem wird erklärt wie man überhaupt RegExes in VB einsetzt.
Schwierigkeitsgrad: | Verwendete API-Aufrufe: GetTickCount, QueryPerformanceCounter, QueryPerformanceFrequency | Download: |
'Dieser Quellcode stammt von http://www.activevb.de 'und kann frei verwendet werden. Für eventuelle Schäden 'wird nicht gehaftet. 'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. 'Ansonsten viel Spaß und Erfolg mit diesem Source! '------- Anfang Projektdatei Regulaere Ausdruecke.vbp ------- ' Es muss ein Verweis auf 'Microsoft VBScript Regular Expressions 5.5' gesetzt werden. '--- Anfang Formular "Form1" alias Regulaere Ausdruecke.frm --- ' Steuerelement: Textfeld "Text1" ' Steuerelement: Schaltfläche "Command1" ' Steuerelement: Beschriftungsfeld "Label1" ' 'Autor: Dominik Auras - neo@tipsntricks.de ' http://www.vbinside.de Option Explicit Private Declare Function GetTickCount Lib "kernel32" () As Long Private Declare Function QueryPerformanceCounter Lib "kernel32" ( _ lpPerformanceCount As LARGE_INTEGER) As Long Private Declare Function QueryPerformanceFrequency Lib "kernel32" ( _ lpFrequency As LARGE_INTEGER) As Long Private Type LARGE_INTEGER lowpart As Long highpart As Long End Type Dim freq As LARGE_INTEGER, calibration As Double Private Sub Command1_Click() Dim Content As String, i As Long, c As Long, e As Long Dim a As String, b As String, reRLE As New RegExp Dim colMatches As MatchCollection, reMatch As Match Dim Ret As String, OldC As String, OldRet As String Dim Start As LARGE_INTEGER, Ende As LARGE_INTEGER e = 100& * 1024& 'Zufälligen Text erzeugen, der nachher komprimiert werden soll Randomize Timer Do While Len(Content) < e i = Rnd * 254 + 1 If i > e - Len(Content) Then i = e - Len(Content) OldC = c Do c = Rnd * 255 Loop Until OldC <> c Content = Content & String(i, c) Loop Debug.Print "Stringgröße: " & Len(Content) Text1.Text = Text1.Text & "Stringgröße: " & Len(Content) & vbCrLf QueryPerformanceCounter Start '############# 'Komprimierung mit VB-Schleife (RLE-Algo) 'API-Zeitmessung a = "" b = "" c = 0 b = Mid$(Content, 1, 1) For i = 1 To Len(Content) a = Mid$(Content, i, 1) If b = a Then c = c + 1 Else Ret = Ret & Chr$(c) & b b = a c = 1 End If Next i Ret = Ret & Chr$(c) & b '############# QueryPerformanceCounter Ende Debug.Print "VB komprimiert " & Len(Ret) & ": "; Debug.Print Int(((CDouble(Ende) - CDouble(Start)) / _ CDouble(freq) * 1000 - calibration) * _ 100000000000#) / 100000000000# & " ms" Text1.Text = Text1.Text & "VB komprimiert " & Len(Ret) & ": " & _ Int(((CDouble(Ende) - CDouble(Start)) / _ CDouble(freq) * 1000 - calibration) * _ 100000000000#) / 100000000000# & " ms" & vbCrLf OldRet = Ret Ret = "" QueryPerformanceCounter Start '############# 'Derselbe Algorithmus zur Komprimierung nun mit einem 'regulären Ausdruck '+ API-Zeitmessung reRLE.Pattern = "(.|\n|\r)\1*" reRLE.Global = True 'das allseits bekannte /../g in Perl etc. Set colMatches = reRLE.Execute(Content) 'RegEx anwenden und _alle_ Fundstellen speichern 'Fundstelle durchgehen For i = 0 To colMatches.Count - 1 Set reMatch = colMatches(i) Ret = Ret & Chr$(reMatch.Length) & reMatch.SubMatches(0) Next i '############# QueryPerformanceCounter Ende Debug.Print "RegEx komprimiert " & Len(Ret) & ": "; Debug.Print Int(((CDouble(Ende) - CDouble(Start)) / _ CDouble(freq) * 1000 - calibration) * _ 100000000000#) / 100000000000# & " ms" Text1.Text = Text1.Text & "RegEx komprimiert " & Len(Ret) & ": " & _ Int(((CDouble(Ende) - CDouble(Start)) / _ CDouble(freq) * 1000 - calibration) * _ 100000000000#) / 100000000000# & " ms" & vbCrLf 'Kontrolle des RLE-Algortihmus If OldRet = Ret Then Debug.Print "Daten stimmen überein" Text1.Text = Text1.Text & "Daten stimmen überein" & vbCrLf End If For i = 1 To Len(Ret) If i > Len(OldRet) Then Debug.Print "pos", i, "char", Mid$(Ret, i, 1) Else If Mid$(Ret, i, 1) <> Mid$(OldRet, i, 1) Then Debug.Print "pos", i, "char", Mid$(Ret, i, 1) End If End If Next i Text1.Text = Text1.Text & "http://www.vbinside.de" & vbCrLf End Sub Private Function CDouble(Num As LARGE_INTEGER) As Double Dim Low As Double, High As Double Low = Num.lowpart High = Num.highpart If Low < 0 Then Low = 4294967296# + Low + 1 If High < 0 Then High = 4294967296# + High + 1 CDouble = Low + High * 4294967296# End Function Private Sub Form_Load() Dim Start As LARGE_INTEGER, Ende As LARGE_INTEGER QueryPerformanceFrequency freq QueryPerformanceCounter Start QueryPerformanceCounter Ende calibration = (CDouble(Ende) - CDouble(Start)) / _ CDouble(freq) * 1000 End Sub '--- Ende Formular "Form1" alias Regulaere Ausdruecke.frm --- '-------- Ende Projektdatei Regulaere Ausdruecke.vbp --------
Tipp-Kompatibilität:
Windows/VB-Version | Win32s | Win95 | Win98 | WinME | WinNT4 | Win2000 | WinXP |
VB4 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
VB5 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
VB6 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.
Archivierte Nutzerkommentare
Klicken Sie diesen Text an, wenn Sie die 10 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.
Kommentar von Klaus Schweitzer am 10.02.2009 um 10:47
If Low < 0 Then Low = 4294967296# + Low + 1
If High < 0 Then High = 4294967296# + High + 1
Ist diese Berechnung von einer signed zu einer unsigned
Variablen richtig ?? Beispiel: 1 Byte: 1111 1111 = 255
ohne Vorzeichen, -1 mit Vorzeichen 2^8 = 256 + (-1) = 255
also müsste die Berechnung für eine Long-Variable doch lauten 2^32 = 4294967296 + Low (ohne "+1")
Kommentar von am 19.08.2005 um 17:32
RegExp sind Teil des VBScript-Paketes vom M$; dieses muß man extra herunterladen und installieren !
Kommentar von Kai Schmalstieg am 16.03.2005 um 09:34
Hallo, ich möchte diesen Tipp testen, kann aber keinen Verweis auf 'Microsoft VBScript Regular Expressions
' 5.5' setzen. Icjh klicke es zwar an und bestätige es, es wird aber irgendwie ignoriert. Was kann ich tun?
Kommentar von Johannes Roth am 06.01.2005 um 20:59
Darum gehts doch gar nicht!!! Es geht hier nicht darum, zu zeigen dass der eine schneller als der andere ist - RegExps werden wie da auch steht schneller - sondern allgemein um Regular Expressions zu zeigen!
Kommentar von Jochen Müller am 18.03.2004 um 09:03
und was bringt das - effektiv fast nichts?!?!? :-)
Rechner (P4 mit HT 3000 MHz). Aber den VB Code könnte man noch optimieren :-)
--
Stringgröße: 102400
VB komprimiert 1590: 35,40227709239 ms
RegEx komprimiert 1590: 35,39276423572 ms
Daten stimmen überein
Kommentar von Oliver Schütze am 07.08.2003 um 16:38
Thomas Fuessl hat zu diesem Thema eine gute DLL geschrieben:
http://www.cae-software.com/freeware/regexp.dll/
Diese DLL hat den Vorteil, dass man nicht das ganze VBS zu installieren braucht.
Gruß,
O. Schütze
Kommentar von Jan-Christian Krause am 25.07.2003 um 12:58
Hallo Leute,
hier noch ein kleiner Hinweis: Wenn Ihr einen Verweis auf die Bibliothek "Microsoft VBScript Regular Expressions 5.5" in Eurem VBA-Projekt erstellt, dann könnt Ihr auch dort reguläre Ausdrücke verwenden ;-).
Ich habe das mit Access 2000 getestet.
Mit freundlichem Gruss
Jan-Christian Krause
Kommentar von Konrad Rudolph am 13.06.2003 um 14:50
Ladet euch doch mal die Beispieldatei runter und schaut euch die Verweise an!
Die RegExp-Klasse ist in der VBS-Dll!
Kommentar von elite01 am 20.05.2003 um 18:05
Bei mir das gleiche es scheint garkein RegExp zu geben hab mich gleich etwas gewundert
Kommentar von Paul am 02.05.2003 um 19:13
Bei mir (VB 6) wird folgende die Fehlermeldung angezeigt:
"User-defined type not defined".
Anschließend wird ", reRLE As New RegExp" markiert.
Was soll ich tun?