Erweiterte Trim-Funktionen

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Kekskiller
Beiträge: 752
Registriert: 14.09.2004 21:39
Kontaktdaten:

Erweiterte Trim-Funktionen

Beitrag von Kekskiller »

Hab für meine paar kleinen Scriptfummeleien eine/zwei erweiterte
Trimfunktion/en geschrieben, sie ermöglichen einem das Wegkürzen
von Leerzeichen rechts ung links. Der String wird direkt per Adresse
manipuliert, teils sehr nützlich:

Code: Alles auswählen

 ;/ schneidet links alle leerzeichen ab
Procedure.s TrimLeft(*sourcestring)
  Protected z
  Protected str$
  str$ = PeekS(*sourcestring)
  For z = 1 To Len(str$)
    If Trim(Left(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen
      Break
    EndIf
  Next
  If z = Len(str$)
    z = 1
  EndIf
  PokeS(*sourcestring, Right(str$, Len(str$) - z + 1))
EndProcedure

;/ schneidet rechts alle leerzeichen ab
Procedure.s TrimRight(*sourcestring)
  Protected z
  Protected str$
  str$ = PeekS(*sourcestring)
  For z = 1 To Len(str$)
    If Trim(Right(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen
      Break
    EndIf
  Next
  If z = Len(PeekS(str$))
    z = 1
  EndIf
  PokeS(*sourcestring, Left(str$, Len(str$) - z + 1))
EndProcedure
Benutzeravatar
Andre
PureBasic Team
Beiträge: 1765
Registriert: 11.09.2004 16:35
Computerausstattung: MacBook Core2Duo mit MacOS 10.6.8
Lenovo Y50 i7 mit Windows 10
Wohnort: Saxony / Deutscheinsiedel
Kontaktdaten:

Beitrag von Andre »

Ich habe mal versucht, dafür noch ein Beispiel zu ergänzen:

Code: Alles auswählen

 ;/ schneidet links alle leerzeichen ab 
Procedure.s TrimLeft(*sourcestring) 
  Protected z 
  Protected str$ 
  str$ = PeekS(*sourcestring) 
  For z = 1 To Len(str$) 
    If Trim(Left(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen 
      Break 
    EndIf 
  Next 
  If z = Len(str$) 
    z = 1 
  EndIf 
  PokeS(*sourcestring, Right(str$, Len(str$) - z + 1)) 
EndProcedure 

;/ schneidet rechts alle leerzeichen ab 
Procedure.s TrimRight(*sourcestring) 
  Protected z 
  Protected str$ 
  str$ = PeekS(*sourcestring) 
  For z = 1 To Len(str$) 
    If Trim(Right(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen 
      Break 
    EndIf 
  Next 
  If z = Len(PeekS(str$)) 
    z = 1 
  EndIf 
  PokeS(*sourcestring, Left(str$, Len(str$) - z + 1)) 
EndProcedure

;- Example
a$ = "    Test-String        "
Debug a$ + "|"

TrimLeft(@a$) 
Debug a$ + "|"


TrimRight(@a$)
Debug a$ + "|"
Irgendwie fände ich es aber doch besser, wenn die Prozeduren mit Rückgabewerten arbeiten würden. Oder worin liegt der besondere Anwendungszweck, übergebene Strings direkt zu manipulieren ?
Bye,
...André
(PureBasicTeam::Docs - PureArea.net | Bestellen:: PureBasic | PureVisionXP)
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

Andre hat geschrieben:Irgendwie fände ich es aber doch besser, wenn die Prozeduren mit Rückgabewerten arbeiten würden.
Dann könntest Du ja gleich RTrim() und LTrim() nehmen.

Ich weiß auch nicht was an diesem Prozeduren "erweitert"
sein soll. Sind bloß beide sehr ineffizient (PeekS+Trim+Left/Right+PokeS).
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Kristel
Beiträge: 72
Registriert: 30.08.2004 00:17

Beitrag von Kristel »

Hab deine Version ein ganz klein wenig überarbeitet.
Dann habe ich die Zeit der beiden Proceduren für Andre's
Beispiel genommen und siehe da: den konstanten Wert
von Len(str$) in len zu speichern bringt etwas.

Hier der Code:

Code: Alles auswählen

#Durchlaeufe = 100000

Procedure.s TrimLeft(*sourcestring) ; Originalfassung
  Protected z 
  Protected str$ 
  str$ = PeekS(*sourcestring) 
  For z = 1 To Len(str$) 
    If Trim(Left(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen 
      Break 
    EndIf 
  Next 
  If z = Len(str$) 
    z = 1 
  EndIf 
  PokeS(*sourcestring, Right(str$, Len(str$) - z + 1)) 
EndProcedure 

Procedure.s TrimRight(*sourcestring) ; Originalfassung
  Protected z 
  Protected str$ 
  str$ = PeekS(*sourcestring) 
  For z = 1 To Len(str$) 
    If Trim(Right(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen 
      Break 
    EndIf 
  Next 
  If z = Len(PeekS(str$)) 
    z = 1 
  EndIf 
  PokeS(*sourcestring, Left(str$, Len(str$) - z + 1)) 
EndProcedure 

Procedure.s TrimLeft_K(*sourcestring) ; von Kristel überarbeitete Fassung 
  Protected z 
  Protected str$
  Protected len.l
  str$ = PeekS(*sourcestring)
  len = Len(str$)
  For z = 1 To len 
    If Trim(Left(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen 
      Break 
    EndIf 
  Next 
  If z = len 
    z = 1 
  EndIf 
  PokeS(*sourcestring, Right(str$, len - z + 1)) 
EndProcedure 

Procedure.s TrimRight_K(*sourcestring) ; von Kristel überarbeitete Fassung
  Protected z 
  Protected str$
  Protected len.l
  str$ = PeekS(*sourcestring)
  len = Len(str$)
  For z = 1 To len 
    If Trim(Right(str$, z)) <> "" ;falls laenge von z ohne leerzeichen von string nicht leer ist, abbrechen 
      Break 
    EndIf 
  Next 
  If z = len 
    z = 1 
  EndIf 
  PokeS(*sourcestring, Left(str$, len - z + 1)) 
EndProcedure 

zeit1 = GetTickCount_()

For x = 1 To #Durchlaeufe
  a$ = "    Test-String        "
  TrimLeft(@a$)
  TrimRight(@a$)
Next  

zeit1 = GetTickCount_() - zeit1

Delay(100)

zeit2 = GetTickCount_()

For x = 1 To #Durchlaeufe
  a$ = "    Test-String        "
  TrimLeft_K(@a$)
  TrimRight_K(@a$)
Next  

zeit2 = GetTickCount_() - zeit2

MessageRequester("Ergebnis","Kekskiller: "+Str(zeit1)+" ms"+Chr(13)+Chr(10)+"Kristel: "+Str(zeit2)+" ms")
Bei 1 Million Durchläufe ergibt sich folgendes Resultat:
Kekskiller: 5531 ms
Kristel: 4343 ms
Original: 922 ms (unter gleichen Bedingungen getestet)

Wenn du schon versuchs RTrim()/LTrim() nach zubauen,
dann wenigstens mit maximalem Speed bei einiger maßen
Codeverständlichkeit. :wink:
Kekskiller
Beiträge: 752
Registriert: 14.09.2004 21:39
Kontaktdaten:

Beitrag von Kekskiller »

Ooops :oops: ...
Ich Idiot hab dpch glatt die Standartfunktionen in der Hilfe übersehen :| ...
Entschuldigt bitte, das hab ich nicht gesehen...

*HÜST*

der eigentliche Sinn darin war, die Funktionen aus einer Dll heraus zu nutzen,
da ich meinen Scriptinterpreter in eine Dll stecken wollte, dort sich aber nur
blanke Werte übergeben ließen, wie eben eine Adresse.

Nunja, ähä... (was für eine Schande...)
Antworten