Page 1 sur 1
Récupération de mots d'une chaine de caractères
Publié : sam. 26/juin/2010 14:12
par G-Rom
Stringfield() est une fonction très pratique pour récupérer des morceaux dans une chaine de caractères.
Mais hélàs il faut que la chaine que l'on passe en paramètres à Stringfield() ne comporte pas d'espace superflu ( en admettant que l'on veut récupérer chacun des mots entre les espaces)
car si il y a un espace entre 2 mots , stringfield() va pioché entre les 2 , c'est à dire rien , et vous renvoyer un #NULL
en admettant que vous avez ce genre de chaine à décortiqué :
Code : Tout sélectionner
TEXT$ = "Cette Chaine de caracteres à des espaces superflu"
; Sans PackString
For i = 1 To CountString(TEXT$,Chr(32))
Debug StringField(TEXT$,i,Chr(32))
Next
le Debbuger renvois des #NULL entre les espaces.
tandis qu'avec PackString :
Code : Tout sélectionner
TEXT$ = "Cette Chaine de caracteres à des espaces superflu"
TEXT$ = PackString(TEXT$,Chr(32))
; avec PackString
For i = 1 To CountString(TEXT$,Chr(32))+1
Debug StringField(TEXT$,i,Chr(32))
Next
C'est quand même plus propre !
Sortie :
Cette
Chaine
de
caracteres
à
des
espaces
superflu
La fameuse fonction :
Code : Tout sélectionner
Procedure.s PackString(string.s, separator.s)
Protected Char.a=0
Protected Fill.a=0
Protected Out$
For i = 1 To Len(string)
Char = Asc(Mid(string,i,1))
If Char <> 32
Fill = 1
Out$ + Chr(Char)
EndIf
If Char = 32 And Fill = 1
Fill = 0
Out$ + separator
EndIf
Next
ProcedureReturn Out$
EndProcedure
Re: Récupération de mots d'une chaine de caractères
Publié : sam. 26/juin/2010 20:02
par Ar-S
Code : Tout sélectionner
TEXT$ = "Cette Chaine de caracteres à des espaces superflu"
; Sans PackString
For i = 1 To CountString(TEXT$,Chr(32))
Debug StringField(TEXT$,i,Chr(32))
Next
TEXT$ = "Cette Chaine de caracteres à des espaces superflu"
TEXT$ = PackString(TEXT$,Chr(32))
; avec PackString
For i = 1 To CountString(TEXT$,Chr(32))+1
Debug StringField(TEXT$,i,Chr(32))
Next
Me renvoient (j'ai pas remis la procedure mais bien sûr je l'utilise)
Code : Tout sélectionner
Cette
Chaine
de
caracteres
à
des
espaces
Cette
Chaine
de
caracteres
à
des
espaces
superflu
Donc il manque "superflu" à la fin du 1er debug. Est-ce le but de packString() ?
Re: Récupération de mots d'une chaine de caractères
Publié : sam. 26/juin/2010 21:18
par G-Rom
Le 1° debug n'utilise pas PackString() , il manque juste +1 à la fin de countstring()

Re: Récupération de mots d'une chaine de caractères
Publié : sam. 26/juin/2010 21:18
par nico
Je ne comprend pas ta démo, avec ce code je n'ai aucun espace superflu:
Code : Tout sélectionner
TEXT$ = "Cette Chaine de caracteres à des espaces superflu"
; Sans PackString
For i = 1 To CountString(TEXT$,Chr(32)) +1
Debug StringField(TEXT$,i,Chr(32))
Next
Re: Récupération de mots d'une chaine de caractères
Publié : sam. 26/juin/2010 21:59
par G-Rom
La mise en forme bouffe les espaces...
Re: Récupération de mots d'une chaine de caractères
Publié : sam. 26/juin/2010 22:24
par nico
J'avais compris entre-temps
Je préfère la version sans le ASC:
Code : Tout sélectionner
Procedure.s PackString(string.s, separator.s)
Protected Char.s
Protected Fill.l=0
Protected Out$
For i = 1 To Len(string)
Char.s = Mid(string,i,1)
If Char <> " "
Fill = 1
Out$ + Char
ElseIf Char = " " And Fill = 1
Fill = 0
Out$ + separator
EndIf
Next
ProcedureReturn Out$
EndProcedure
Sympa ta procédure, je ne l'aurais pas fait de cette façon mais la tienne me parait bien meilleure.

Re: Récupération de mots d'une chaine de caractères
Publié : sam. 26/juin/2010 23:12
par nico
IL semble que cette version soit deux mille fois plus rapide que la tienne (d'après des tests sur un fichiers de 62.2Ko):
la tienne autour de 20000 ms
la nouvelle version entre 10 et 30 ms
C'est vrai que j'avais remarqué que les opérations sur les chaines avec PB étaient rapide mais là c'est impressionnant.
Code : Tout sélectionner
Procedure.s PackString2(string.s, separator.s)
Protected Chaine$,Chaine2$
Chaine$=Trim(string)
Repeat
Chaine2$=Chaine$
Chaine$ = ReplaceString(Chaine$, separator+separator, separator)
Until Chaine2$=Chaine$
ProcedureReturn Chaine$
EndProcedure
La procédure de test (Il vous faudra créer le fichier test):
Code : Tout sélectionner
ReadFile(0, "test.txt")
longueur=Lof(0)
*mem=AllocateMemory(longueur)
ReadData(0,*mem,longueur)
TEXT$=PeekS(*mem)
CloseFile(0)
Procedure.s PackString(string.s, separator.s)
Protected Char.s
Protected Fill.l=0,i.l
Protected Out$
For i = 1 To Len(string)
Char.s = Mid(string,i,1)
If Char <> " "
Fill = 1
Out$ + Char
ElseIf Char = " " And Fill = 1
Fill = 0
Out$ + separator
EndIf
Next
ProcedureReturn Out$
EndProcedure
Procedure.s PackString2(string.s, separator.s)
Protected Chaine$,Chaine2$
Chaine$=Trim(string)
Repeat
Chaine2$=Chaine$
Chaine$ = ReplaceString(Chaine$, separator+separator, separator)
Until Chaine2$=Chaine$
ProcedureReturn Chaine$
EndProcedure
TempsDepart = ElapsedMilliseconds()
TEXT1$ = PackString(TEXT$,Chr(32))
TempsEcoule = ElapsedMilliseconds()-TempsDepart
MessageRequester( "Info","Temps écoulé : "+Str(TempsEcoule)+" millisecondes" )
CreateFile(0,"test1.txt")
WriteString(0,TEXT1$)
CloseFile(0)
TempsDepart = ElapsedMilliseconds()
TEXT2$ = PackString2(TEXT$,Chr(32))
TempsEcoule = ElapsedMilliseconds()-TempsDepart
MessageRequester( "Info","Temps écoulé : "+Str(TempsEcoule)+" millisecondes" )
CreateFile(0,"test2.txt")
WriteString(0,TEXT2$)
CloseFile(0)
Re: Récupération de mots d'une chaine de caractères
Publié : dim. 27/juin/2010 0:23
par G-Rom
Merci nico , j'avais pas pensé à ce genre de différence !
c'est certainement du au fait que je parcours la chaine , je vois pas comment optimisé sans replacestring() du coup ?
Re: Récupération de mots d'une chaine de caractères
Publié : dim. 27/juin/2010 17:50
par Scrat
Salut
y' ça aussi
Code : Tout sélectionner
s.s="Cette Chaine de caracteres à des espaces superflu 123"
Dim result$(0)
CreateRegularExpression(0,"[\H]+[\S]?")
NbFound = ExtractRegularExpression(0,s , Result$())
For k = 0 To NbFound-1
Debug Result$(k)
Next
FreeRegularExpression(0)
a+
edit : \s remplacé par \S c'est mieux
Re: Récupération de mots d'une chaine de caractères
Publié : dim. 27/juin/2010 18:23
par SPH
Extremement simple et court :
Code : Tout sélectionner
txt$="Des espaces superflus quelque part ???? "
Repeat
lg=Len(txt$)
txt$=ReplaceString(txt$," "," ")
Until Len(txt$)=lg
Debug txt$

Re: Récupération de mots d'une chaine de caractères
Publié : dim. 27/juin/2010 18:35
par Scrat
oui mais je crois qu'il veut spliter la chaine en mots
A+
Re: Récupération de mots d'une chaine de caractères
Publié : lun. 30/août/2010 17:31
par GeBonet
Bonjour,
Voilà également une forme.... Le "truc" substituer 2 blancs par un point... Puis les retirer
Pour tester et après copie placer des espaces dans la chaine$... à boucher..
BBcode n'en veut pas lui...
Code : Tout sélectionner
; ---------------------------------------------------
; -- Autres évacuateur de blancs... GeBonet --
; ---------------------------------------------------
;
Chaine$="Je suis une chaîne contenant des espaces variables"
Debug "Au début :"
Debug "> "+Chaine$
;---------- Phase 1 : Remplace par des points ------
Repeat
If FindString(Chaine$," ",1) ; Ici <2> blancs par <1> point
ReplaceString(Chaine$,chr(32)+chr(32),".",#PB_String_InPlace,1):k=1 ; Flag pour boucler..
Else :k=0:EndIf
Until k=0
;
;---------- Phase 2 : Retire les points ------
;
Repeat
If FindString(Chaine$,"..",1) Or FindString(Chaine$,"."+chr(32),1)
Repeat
x=FindString(Chaine$,"..",1)-1
If x>0
chaine$=Left(Chaine$,x)+Mid(Chaine$,x+3)
EndIf
Until x<1
x=FindString(Chaine$,"."+chr(32),1)-1
Repeat
If x>0
x=FindString(Chaine$,"."+chr(32),1)-1
chaine$=Left(Chaine$,x)+Mid(Chaine$,x+2)
EndIf
Until x<1
EndIf
Until CountString(Chaine$,".")=0
;
Debug "> Forme finale : "
Debug "> "+Chaine$
;
; Utilisation de "StringField" pour finir...
;
For i = 1 To CountString(Chaine$,Chr(32))+1
Debug StringField(Chaine$,i,Chr(32))
Next
End
;
Bon, ce n'est qu'un autre point de vue...

Re: Récupération de mots d'une chaine de caractères
Publié : lun. 30/août/2010 21:31
par GallyHC
Bonjour,
Apres quelque reflexion j'ai essaye de faire une fonction courte. J'espere ne pas etre hors sujet

.
Code : Tout sélectionner
Define i.l
Define result.s
Define chaine.s = "Cette Chaine de caracteres à des espaces superflu"
For i = 1 To CountString(chaine,Chr(32)) + 1
result = Trim(StringField(chaine,i,Chr(32)))
If result <> ""
Debug result
EndIf
Next i
Cordialement,
GallyHC
Re: Récupération de mots d'une chaine de caractères
Publié : lun. 30/août/2010 22:44
par GeBonet
GallyHC a écrit :
Après quelque réflexion j'ai essaye de faire une fonction courte. J'espère ne pas être hors sujet

.
Ben non, c'est pas hors sujet... C'est aussi une solution dans le cas d'espaces...
Ma démarche est autres. Elle est de montrer que l'on peut
utiliser des moyens détournés.
Comme dans l'exemple que je donne, d'utiliser un autre marqueur qui lui est plus contrôlable vu que c'est toi même qui le place (
ici j'ai placé des points, car justement dans la phrase il pourrait y en avoir et alors serait inclus avec le mots le précédent avec ta forme. etc.).
Essaye :
Code : Tout sélectionner
Define chaine.s = "Cette Chaine de caractères. à des espaces. superflu"
Mais dans le cas qui ne serait que composée de mots et d'espaces (et même de trop).
Ta forme est beaucoup plus simple !
De plus je ne suis pas certain que la volonté de départ était de décomposer en mots, mais d'évacuer les espaces ou autres caractères récurrent...
En fait tout dépend de ce que l'on veux en faire... Si par exemple c'était un analyseur syntaxique... Il serait préférable de "capturer" les mots un par un au fur et à mesure qu'ils sont introduits... Cela permet une aide à compléter la frappe avec des mots valides lorsqu'il s'agit de "langage" ou "pseudo-langage". Enfin c'est ce que j'en pense...
