[PB4] Split() et Join()

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

[PB4] Split() et Join()

Message par Flype »

Pour splitter une une chaine de caractères en liste ou tableau et vice versa.

Code : Tout sélectionner

; Split() functions, Purebasic 4.0+

Macro CountArray(array)
  ( PeekL( @array-8 ) )
EndMacro

Procedure.l SplitArray(array.s(1), text.s, separator.s = ",") ; String to Array
  
  Protected index.l, size.l = CountString(text, separator)
  
  ReDim array.s(size)
  
  For index = 0 To size
    array(index) = StringField(text, index + 1, separator)
  Next
  
  ProcedureReturn size
  
EndProcedure
Procedure.s JoinArray(array.s(1), separator.s = ",") ; Array to String
  
  Protected index.l, result.s, size.l = CountArray(array()) - 1
  
  For index = 0 To size
    result + array(index)
    If (index < size)
      result + separator
    EndIf
  Next
  
  ProcedureReturn result
  
EndProcedure
Procedure.l SplitList(list.s(), text.s, separator.s = ",") ; String to List
  
  Protected index.l, size.l = CountString(text, separator)
  
  For index = 0 To size
    If AddElement(list())
      list() = StringField(text, index + 1, separator)
    EndIf
  Next
  
  ProcedureReturn size
  
EndProcedure
Procedure.s JoinList(list.s(), separator.s = ",") ; List to String
  
  Protected result.s, size.l = CountList(list()) - 1
  
  ForEach list()
    result + list()
    If (ListIndex(list()) < size)
      result + separator
    EndIf
  Next
  
  ProcedureReturn result
  
EndProcedure

; Examples

string.s = "abc,defg,hi,jklmop,qrs,tuv,wxyz"

; string -> array -> string

Dim a.s(0)

size.l = SplitArray(a(), string, ",")

For i = 0 To size
  Debug a(i)
Next

Debug JoinArray(a())

; string -> list -> string

NewList b.s()

If SplitList(b(), string)
  ForEach b()
    Debug b()
  Next
EndIf

Debug JoinList(b())

;--
Image
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Simpa.
Perso, je préfère les noms de fonctions Implode et Explode (cf PHP) :wink:
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

ah oui c'est pas mal non plus la syntaxe php.
je viens de vérifier sur php.net :
http://fr.php.net/manual/fr/function.implode.php
http://fr.php.net/manual/fr/function.explode.php

du coup, voici la syntaxe php (explode supporte une limite négative) :

Code : Tout sélectionner

; 
; Join()/Split()
; 
; Php Syntax:
; implode.s( glue.s, pieces.s(1) )
; explode.l( separator.s, string.s , limit.l = 0 )
; 
; http://fr.php.net/manual/fr/function.implode.php
; http://fr.php.net/manual/fr/function.explode.php
; 

Macro CountArray(array)
  ( PeekL( @array-8 ) )
EndMacro

Procedure.l explode_array(array.s(1), separator.s, string.s, limit.l = 0) ; String to Array
  
  Protected index.l, size.l = CountString(string, separator)
  
  If (limit > 0)
    size = limit - 1
  ElseIf (limit < 0)
    size + limit
  EndIf
  
  ReDim array.s(size)
  
  For index = 0 To size
    array(index) = StringField(string, index + 1, separator)
  Next
  
  ProcedureReturn size
  
EndProcedure
Procedure.s implode_array(glue.s, pieces.s(1)) ; Array to String
  
  Protected index.l, string.s, size.l = CountArray(pieces()) - 1
  
  For index = 0 To size
    string + pieces(index)
    If (index < size)
      string + glue
    EndIf
  Next
  
  ProcedureReturn string
  
EndProcedure
Procedure.l explode_list(list.s(), separator.s, string.s, limit.l = 0) ; String to List
  
  Protected index.l, size.l = CountString(string, separator)
  
  If (limit > 0)
    size = limit - 1
  ElseIf (limit < 0)
    size + limit
  EndIf
  
  For index = 0 To size
    If AddElement(list())
      list() = StringField(string, index + 1, separator)
    EndIf
  Next
  
  ProcedureReturn size
  
EndProcedure
Procedure.s implode_list(glue.s, pieces.s()) ; List to String
  
  Protected string.s, size.l = CountList(pieces()) - 1
  
  ForEach pieces()
    string + pieces()
    If (ListIndex(pieces()) < size)
      string + glue
    EndIf
  Next
  
  ProcedureReturn string
  
EndProcedure

; Examples

input.s = "feel the power of purebasic :-)"

; string -> array -> string

Dim a.s(0)

size.l = explode_array(a(), " ", input, -3)

For i = 0 To size
  Debug a(i)
Next

Debug implode_array("  =|=  ", a())

; string -> list -> string

NewList b.s()

If explode_list(b(), " ", input, 5)
  ForEach b()
    Debug b()
  Next
EndIf

Debug "[" + implode_list("][", b()) + "]"

;--
Image
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

Voici un remplacement très basic de la fonction StringField de purebasic.
Elle permet simplement de pouvoir passer en argument un séparateur d'une longueur > 1.
Du coup, cumulé aux fonctions ci dessus le comportement est réellement comme en PHP.

Code : Tout sélectionner

Macro StringField(string, index, separator)
  StringFieldEx(string, index, separator)
EndMacro

Procedure.s StringFieldEx(string.s, index.l, sep.s)
  
  Protected i.l, pos.l, field.s, lSep.l = Len(sep)
  
  For i = 1 To index
    pos = FindString(string, sep, 1)
    If pos
      field = Left(string, pos - 1)
    Else
      field = string
    EndIf
    string = Mid(string, pos + lSep, Len(string))
  Next
  
  ProcedureReturn field
  
EndProcedure
Image
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Flype a écrit :

Code : Tout sélectionner

Macro StringField(string, index, separator)
  StringFieldEx(string, index, separator)
EndMacro

Procedure.s StringFieldEx(string.s, index.l, sep.s)
  
  Protected i.l, pos.l, field.s, lSep.l = Len(sep)
  
  For i = 1 To index
    pos = FindString(string, sep, 1)
    If pos
      field = Left(string, pos - 1)
    Else
      field = string
    EndIf
    string = Mid(string, pos + lSep, Len(string))
  Next
  
  ProcedureReturn field
  
EndProcedure
J'arrive pas trop à comprendre ce que tu veux faire. Par contre la ligne : "string = Mid(string, pos + lSep, Len(string))" me parait très bizarre et pas rigoureuse, vu que tu extrait une chaîne de la taille de ton string, sans commencer à 1.
C'est parce que tu ne voulais pas calculer la vraie position finale ou c'est "normal" ?
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Avatar de l’utilisateur
flaith
Messages : 1487
Inscription : jeu. 07/avr./2005 1:06
Localisation : Rennes
Contact :

Message par flaith »

j'ai ce petit code :

exlode.pb

Code : Tout sélectionner

str$ = "Bonjour, je suis une chaîne séparé !!!"

Procedure explode(separator.s, string.s, limit.l = 99)
  NbWord = CountString(string, separator)
  If limit < NbWord
    NbWord = limit-1
  EndIf
  For k=1 To NbWord+1
    PrintN (StringField(string, k, separator))
  Next
EndProcedure

If OpenConsole()
  explode(" ",str$) ;,2)
EndIf

Input()
CloseConsole()
Répondre