Seite 5 von 12

Verfasst: 30.03.2007 15:17
von ts-soft
AND51 hat geschrieben: Hätte hier mal beispielsweise eine Funktion von Perl nach PB portiert: split()

Code: Alles auswählen

Procedure splitStringToArray(Array.s(1), String.s, Separator.s=" ")
	string+Separator
	Protected n, num=CountString(String, Separator)
	ReDim Array.s(num-1)
	For n=1 To num
		Array(n-1)=StringField(String, n, Separator)
	Next
	ProcedureReturn num
EndProcedure


Dim woerter.s(51)
anzahl=splitStringToArray(woerter(), "I love PureBasic")

For n=0 To anzahl-1
	Debug woerter(n)
Next
Teilt einen String anhand eines Trennzeichens auf und speichert die Teilstrings in Arrays. Das Trennzeichen darf nur ein Zeichen umfassen (bedingt durch StringField).
Hier mal etwas schneller, aber bestimmt noch zu optimieren :mrgreen:

Code: Alles auswählen

Procedure splitStringToArray(Array.s(1), String.s, Separator.s = " ")
  Protected *s.Character = @String, Count.l, nString.s, n.l, nSeparator.l = Asc(Separator)
  If String <> ""
    While *s\c <> 0
      If *s\c = nSeparator
        Count + 1
      EndIf
      *s + SizeOf(Character)
    Wend
    *s = @String
    ReDim Array.s(Count)
    For n = 0 To Count
      While *s\c <> nSeparator And *s\c <> 0
        nString + Chr(*s\c)
        *s + SizeOf(Character)
      Wend
      Array.s(n) = nString
      nString = ""
      *s + SizeOf(Character)
    Next
    ProcedureReturn Count + 1
  EndIf
EndProcedure

Dim woerter.s(51)
anzahl=splitStringToArray(woerter(), "I love PureBasic")

For n=0 To anzahl-1
  Debug woerter(n)
Next

Verfasst: 30.03.2007 15:43
von Nero
Frage: DU kennst doch sicherlich || und or. Warum kann ich das hier nicht schreiben:
Bei Variablen must du immer || nehmen.
http://perldoc.perl.org/perlop.html#Log ... 2c-and-and

Verfasst: 30.03.2007 16:24
von edel
Kiffi hat geschrieben:
edel hat geschrieben:schonmal an pcre oder sogar an Boost gedacht ?
na klar, hast Du etwa unsere romantischen Skype-Abendunterhaltungen vergessen (u.a. auch mit Delphi)? ;-)
Jetzt wo du es sagst ...

ts kommt auch immer mit Funktionen an die ich geschrieben haben soll ... , ich werd halt alt :lol:
Kiffi hat geschrieben: <träum>
Wäre halt schön mit Perl oder PHP oder Schiess-Mich-Tot ein AllInOne-Paket
zu bekommen, mit dem man RegExp, XML, SQLite, etc. pp, erschlagen
könnte.
</träum>
Das meiste davon hast du ja schon gemacht. Noch etwas vereinfachen,
zusammen packen und schon ist dein "AllInOne-Paket" fertig ;-)

Verfasst: 30.03.2007 17:21
von AND51
> Hier mal etwas schneller
Wollte auch erst mit Pointer arbeiten, aber ich kann heut nicht klar denken... Sollte mich erst auskurieren...

Hinweis: StringField akzeptiert blöderweise nur 1 Zeichen als Separator, Perl-split() ermöglicht aber mehrere Zeichen, weshalb ich erst an Pointer dachte.

Verfasst: 30.03.2007 17:49
von Nero
Noch ne möglichkeit

Code: Alles auswählen

Procedure split(Array.s(1), String.s, Separator.s = " ")  
  Laenge.l = Len(String)

  count.l = 0
  For x = 0 To Laenge  
    If PeekS(@String + x, 1) = Separator
      count + 1
      ReDim Array.s(count)
    Else
      Array.s(count) + PeekS(@String + x, 1)
    EndIf     
  Next
EndProcedure

Dim NewArray.s(0)
split(NewArray(), "So nun sollte es korreckt funktionieren") 

For x = 0 To PeekL(@NewArray() - 8) - 1 
  Debug NewArray(x)
Next

Verfasst: 30.03.2007 17:51
von Kaeru Gaman
Pearl ist doch die Tochter von Mr.Crabs.... was wollt ihr den alle von der?

Verfasst: 30.03.2007 18:21
von edel
AND51 hat geschrieben: Hinweis: StringField akzeptiert blöderweise nur 1 Zeichen als Separator, Perl-split() ermöglicht aber mehrere Zeichen, weshalb ich erst an Pointer dachte.
Entweder man schreibt was neues oder benutzt das was da ist.

Beispiel :

Code: Alles auswählen

  ImportC "msvcrt.lib"
    CompilerIf #PB_Compiler_Unicode
    strtok(*string,*seps) As "_wcstok"
    CompilerElse
    strtok(*string,*seps) As "_strtok" 
    CompilerEndIf 
  EndImport
  
  Define Token.l
  Define String.s
  Define Seps.s
  
  String = "Die ist ein TestString, mit viel Unsinn !"
  Seps   = " ," ; Leerzeichen , Komma
  
  Token = strtok(@String,@Seps)
  
  While Token
    
    Debug PeekS(Token)
    
    Token = strtok(#Null,@Seps)
  Wend

Verfasst: 30.03.2007 20:47
von AND51
Kaeru Gaman hat geschrieben:Pearl ist doch die Tochter von Mr.Crabs.... was wollt ihr den alle von der?
Kannst du solche Spaßbeiträge mal bitte lassen? Was solln das jetzt wieder? Außerdem reden wir nicht von Pearl, sondern Perl. War echt witzig :twisted:


> Entweder man schreibt was neues oder benutzt das was da ist.
In diesem Fall warte ich dann doch lieber, bis Fred endlich mal nen vernünftigen StringField einbaut /:->

Hast aber Recht. Frage: Wie funktioniert deine Version? Soll die auch mehrere Zeichen unterstützen?
Wenn ja: Warum trennt deine Funktion anscheinen nur gemäß eines Leerzeichens?
Wenn nein: Wo bleibt das Komma?
Oder ist das eine Funktion, die mehere Trennzeichen in einem Vorgang unterstützt
Debugger hat geschrieben:Die
ist
ein
TestString
mit
viel
Unsinn
!

Verfasst: 30.03.2007 20:51
von edel
Es sind 2 (zwei) Trennzeichen, warum sollte also das Komma angezeigt werden ?

Mehr kannst du auf MSDN nachlesen.

Verfasst: 30.03.2007 21:07
von AND51
OK, also dein Trennzeichen lautet also " ," aber wieso trennt er dann auch noch dortr, wo nur ein Leerzeichen ist?

Würde StringField() mit mehreren Zeichen arbeiten, käme beim Debugger folgendes raus.
Die ist ein TestString
mit viel Unsinn !
Das würd ich jetzt auch von deinem Code erwarten.

Ich les mal die MSDN.

//Edit:
Da siehste was ich meine, deine Funktion arbeitet nciht, wie erwartet:

Code: Alles auswählen

  ImportC "msvcrt.lib" 
    CompilerIf #PB_Compiler_Unicode 
    strtok(*string,*seps) As "_wcstok" 
    CompilerElse 
    strtok(*string,*seps) As "_strtok" 
    CompilerEndIf 
  EndImport 
  
  Define Token.l 
  Define String.s 
  Define Seps.s 
  
  String = "DieAistBeinABTestStringAmitAvielAUnsinnB!" 
  Seps   = "AB" ; Leerzeichen , Komma 
  
  Token = strtok(@String,@Seps) 
  
  While Token 
    
    Debug PeekS(Token) 
    
    Token = strtok(#Null,@Seps) 
  Wend
Deiner Beschreibung nach sollte er nur bei "ein" trennen, tut er aber nicht.
MSDN hat geschrieben:strDelimit
Set of delimiter characters.
Also unterstützt deine Funktion indirekt auch wieder nur 1 Zeichen.