String-Vergleich mit Wildcards
Verfasst: 18.08.2006 17:02
Hi Leute!
Da gewünscht wurde, dass man bei meiner kleinen Datenbank beim Suchen
auch Wildcards benutzen kann, habe ich mich eben mal rangesetzt und etwas
zusammengeschustert, was nicht schön aussieht, aber funktioniert.
Ein paar Kommentare hätte ich mir wohl mal leisten sollen, aber naja.
Der optionale Suchmasken-Parameter ist für Suchen gedacht, die man immer
wieder mit der selben Suchmaske ausführen will.
///Edit 1:
Added: Nach Remis Idee ist der Code nun auch kompatibel mit UNICODE-Strings.
///Edit 2:
Changed: Jetzt wird das Array nicht mehr gebraucht. Somit ist die
Procedure jetzt speicherschonender und sogar minimal schneller.
Hier ist der Code:
Da gewünscht wurde, dass man bei meiner kleinen Datenbank beim Suchen
auch Wildcards benutzen kann, habe ich mich eben mal rangesetzt und etwas
zusammengeschustert, was nicht schön aussieht, aber funktioniert.
Ein paar Kommentare hätte ich mir wohl mal leisten sollen, aber naja.
Der optionale Suchmasken-Parameter ist für Suchen gedacht, die man immer
wieder mit der selben Suchmaske ausführen will.
///Edit 1:
Added: Nach Remis Idee ist der Code nun auch kompatibel mit UNICODE-Strings.
///Edit 2:
Changed: Jetzt wird das Array nicht mehr gebraucht. Somit ist die
Procedure jetzt speicherschonender und sogar minimal schneller.
Hier ist der Code:
Code: Alles auswählen
Procedure CompareWithWildcards(String.s, StringToFind.s = "")
Static oldStringToFind.s, max.l
Static NewList vPart.s()
Protected *c.Character, p.s = "", a.l, fr.l = #False, *c2.Character, *tmp
Macro Add(zstring)
If AddElement(vPart()) : vPart() = zstring : max + 1 : EndIf
EndMacro
If StringToFind = ""
If oldStringToFind = "" : ProcedureReturn #False : EndIf
StringToFind = oldStringToFind
Else
oldStringToFind = StringToFind
ClearList(vPart())
*c = @StringToFind : a = 0 : max = 0
While *c\c
If *c\c = '*'
If a
If ((Not PeekC(*c - SizeOf(Character)) = '*') And fr) Or max = 0
If max Or fr : Add(p) : EndIf
Add("*") : p = ""
fr = #False
Else
p = ""
EndIf
Else
Add("*")
EndIf
ElseIf *c\c = '?'
If fr Or a = 0 : p + Chr(*c\c) : EndIf
Else
p + Chr(*c\c)
fr = #True
EndIf
*c + SizeOf(Character) : a + 1
Wend
If p <> "" : Add(p) : EndIf
max - 1
EndIf
a = 0
*c = @String
FirstElement(vPart())
Repeat
If vPart() = "*"
If a = max
ProcedureReturn #True
EndIf
*tmp = *c
NextElement(vPart())
Repeat
*c = *tmp
*c2 = PeekL(@vPart()) ;anders als bei Arrays
While *c2\c
If *c\c = 0 : ProcedureReturn #False : EndIf
If *c2\c <> *c\c And *c2\c <> '?' : Break : EndIf
*c + SizeOf(Character) : *c2 + SizeOf(Character)
Wend
If *c2\c = 0 : Break : EndIf
*tmp + SizeOf(Character)
ForEver
*c = *tmp
Else
*c2 = PeekL(@vPart()) ;anders als bei Arrays
While *c2\c
If *c\c = 0 : ProcedureReturn #False : EndIf
If *c2\c <> *c\c And *c2\c <> '?' : ProcedureReturn #False : EndIf
*c + SizeOf(Character) : *c2 + SizeOf(Character)
Wend
If a = max And *c\c : ProcedureReturn #False : EndIf
NextElement(vPart())
EndIf
a + 1
Until a = max + 1
ProcedureReturn #True
EndProcedure
Debug CompareWithWildcards("May", "*May*")
Debug CompareWithWildcards("Mayer ist schlau", "M??er *schlau*")
Debug CompareWithWildcards("Meyer ist sehr schlauer", "")
Debug CompareWithWildcards("Meier ist ultra schlauer", "")
Debug CompareWithWildcards("Mayar ist ganz schön schlau", "")
text.s="2030501"
Suchmuster.s="??3"
Debug CompareWithWildcards(text, Suchmuster)
text.s="2030501"
Suchmuster.s="*5"
Debug CompareWithWildcards(text, Suchmuster)
text.s="2030501"
Suchmuster.s="*6?1"
Debug CompareWithWildcards(text, Suchmuster)