Seite 1 von 1

Problem mit Stringvergleich (Code aus Forum Archiv)

Verfasst: 23.10.2004 11:59
von bvc
Hallo ich habe folgendes Problem:

Folgender Code stammt von @NicTheQuick und funktioniert bis auf 3 Funktionen die ich dringend benötige auch prima und schnell. Danke @NicTheQuick

Code: Alles auswählen

Procedure CompareWithWildcards(*String.BYTE, *WC.BYTE) 
  Protected *z1.BYTE, *z2.BYTE, *z3.BYTE 
  Protected a.l, WCLength.l, StringLength.l 
  
  *z1 = *WC 
  *z2 = *String 
  Repeat 
    If *z1\b = '*' 
      *z3 = *z1 + 1 
      If *z3\b = 0                   ;Wenn der Stern am Schluss steht 
        ProcedureReturn #True 
      Else 
        If *z3\b = 0                  ;Wenn der String am Ende ist 
          ProcedureReturn #False 
        Else 
          *z3 = *z1 + 1 
          If *z3\b = *z2\b 
            *z1 + 1 
          Else 
            *z2 + 1 
          EndIf 
        EndIf 
      EndIf 
    ElseIf *z1\b = '?' 
      If *z2\b = 0 
        ProcedureReturn #False 
      Else 
        *z1 + 1 
        *z2 + 1 
      EndIf 
    Else 
      If *z1\b = *z2\b 
        *z1 + 1 
        *z2 + 1 
      Else 
        ProcedureReturn #False 
      EndIf 
    EndIf 
  Until *z1\b = 0 
  ProcedureReturn #True 
EndProcedure 
Text.s="2030501"
Suchmuster.s="??3"
Debug CompareWithWildcards(@Text,@Suchmuster) ; liefert True, sollte aber false sein weil nach der 3 im 
                                              ; Suchmuster kein "*" steht
Text.s="2030501"
Suchmuster.s="*5"
Debug CompareWithWildcards(@Text,@Suchmuster) ; liefert True, sollte aber false sein weil nach 
                                              ; einem String gesucht wird, der am Ende eine 5 stehen hat
Text.s="2030501"
Suchmuster.s="*6?1"
Debug CompareWithWildcards(@Text,@Suchmuster) ; liefert True, sollte aber false sein 

Ich hoffe, mir kann jemand helfen

Verfasst: 23.10.2004 14:36
von Danilo
Hat zwar nichts direkt mit Deinem Problem zu tun, aber
vielleicht solltest Du dafür einfach gleich die RegExp und
RegExpEx Libs von FloHimself nehmen (PureArea.net).

Regular Expressions sind für sowas weit verbreitet, falls
es für Dich eine Möglichkeit gibt noch schnell umzusteigen.

Verfasst: 24.10.2004 11:46
von bvc
@Danilo

Danke für die schnelle Antwort. Ich habe mir die Doku von FloHimself angesehen. Ich werde jetzt mal ein paar Tests machen und sehen, ob ich damit zum Ziel komme.

Hat jemand schon Erfahrung mit der Lib?

Verfasst: 18.08.2006 15:53
von NicTheQuick
Habe die Funktion jetzt komplett neu gecodet.
Sie ist darauf optimiert mehrmals mit der selben Suchmaske aufgerufen zu
werden, indem man sie beim zweiten Aufruf nicht mehr angibt oder wieder
die selbe benutzt.

Intern wird die Suchmaske zuerst zerlegt und in einem Array gespeichert,
das bei erneutem Aufruf mit der selben Suchmaske nicht wieder neu
generiert wird, sondern durch [c]Static[/c] im Speicher bleibt.

Aber hier erstmal der Code. Er sieht kompliziert ist aus und er ist es auch,
wie ich selbst finde. Vielleicht wären ein paar Kommentare gut gewesen. :mrgreen:

Code: Alles auswählen

Procedure CompareWithWildcards(String.s, StringToFind.s = "")
  Static oldStringToFind.s, max.l
  Static NewList vPart.s(), Dim Part.s(0)
  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 - 1) = '*') 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 + 1 : a + 1
    Wend
    
    If p <> "" : Add(p) : EndIf
    max - 1
    Redim Part.s(max)
    a = 0 : ForEach vPart() : Part(a) = vPart() : a + 1 : Next
  EndIf
  
  a = 0
  *c = @String
  Repeat
    If Part(a) = "*"
      If a = max 
        If *c\c
          ProcedureReturn #True
        Else
          ProcedureReturn #False
        EndIf
      EndIf
      *tmp = *c
      Repeat
        *c = *tmp
        *c2 = @Part(a + 1)
        While *c2\c
          If *c\c = 0 : ProcedureReturn #False : EndIf
          If *c2\c <> *c\c And *c2\c <> '?' : Break : EndIf
          *c + 1 : *c2 + 1
        Wend
        If *c2\c = 0 : Break : EndIf
        *tmp + 1
      ForEver
      *c = *tmp
    Else
      *c2 = @Part(a)
      While *c2\c
        If *c\c = 0 : ProcedureReturn #False : EndIf
        If *c2\c <> *c\c And *c2\c <> '?' : ProcedureReturn #False : EndIf
        *c + 1 : *c2 + 1
      Wend
      If a = max And *c\c : ProcedureReturn #False : EndIf
    EndIf
    a + 1
  Until a = max + 1
  
  ProcedureReturn #True
EndProcedure

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)
Dieser Code soll jetzt auch verwendet werden für meine kleine
Datenbank, die im "Codes, Tipps und Tricks"-Forum zu finden ist.

Verfasst: 19.08.2006 08:07
von bvc
Das sieht ja spannend aus. Ich werde es nächste Woche mal testen. Vielen Dank.

Verfasst: 19.08.2006 08:41
von ts-soft
bvc hat geschrieben:Das sieht ja spannend aus. Ich werde es nächste Woche mal testen. Vielen Dank.
Bei 2 Jahren wartezeit, kommst dann wirklich nicht mehr auf ne Woche an :D

Verfasst: 19.08.2006 13:57
von bvc
so ises.

ich konnte mir damals mit nem workaround helfen. musste also nicht weiter auf irgentwelche tränendrüsen drücken :)

wenn es nun funktioniert, habe ich noch ein paar ideen für meine Anwendung, daher .... besser spät als nie.

:allright: