Problem mit Stringvergleich (Code aus Forum Archiv)

Für allgemeine Fragen zur Programmierung mit PureBasic.
bvc
Beiträge: 37
Registriert: 09.09.2004 16:02

Problem mit Stringvergleich (Code aus Forum Archiv)

Beitrag 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
manchmal weiß auch ich etwas, ich erinnere mich bloß schlecht daran
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag 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.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
bvc
Beiträge: 37
Registriert: 09.09.2004 16:02

Beitrag 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?
manchmal weiß auch ich etwas, ich erinnere mich bloß schlecht daran
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag 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.
bvc
Beiträge: 37
Registriert: 09.09.2004 16:02

Beitrag von bvc »

Das sieht ja spannend aus. Ich werde es nächste Woche mal testen. Vielen Dank.
manchmal weiß auch ich etwas, ich erinnere mich bloß schlecht daran
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
bvc
Beiträge: 37
Registriert: 09.09.2004 16:02

Beitrag 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:
manchmal weiß auch ich etwas, ich erinnere mich bloß schlecht daran
Antworten