Suppression de chaines entre guillemet dans un fichier texte

Résolu
cs_philcam Messages postés 132 Date d'inscription dimanche 12 août 2001 Statut Membre Dernière intervention 17 octobre 2008 - 28 août 2005 à 13:34
cs_philcam Messages postés 132 Date d'inscription dimanche 12 août 2001 Statut Membre Dernière intervention 17 octobre 2008 - 30 août 2005 à 19:37
Salut à tous,

je suis en train de faire une routine pour traiter les fichiers PGN (parties d'échecs).

Le but serait de supprimer les commentaires des parties pour qu'elles soient plus lisibles.
Les commentaires sont dans le fichier pgn (fichier texte) entre des guillemets, exemple :

1.e4 {(e2e4) +0.02/99} c5 2.Nc3 {(Cb1c3) +0.02/99} Nc6 3.g3 {(g2g3) +0.02/99}
Nf6 {(Cg8f6 Cg1f3 d7d5 e4xd5 Cf6xd5 Ff1c4 e7e6 00 Ff8e7 d2d3) 0.00/10 1} 4.Bc4
{(Ff1c4 e7e6 Cg1f3 d7d5 e4xd5 e6xd5 Dd1e2+ Fc8e6) -0.14/7 4} e6 {(e7e6 d2d3 d7d5 Fc4b5
Fc8d7 Cg1f3 d5d4 Fb5xc6 Fd7xc6 Cc3e2) +0.25/10 2} 5.Bb5 etc...

devient :

1.e4 c5 2.Nc3 Nc6 3.g3 Nf6 4.Bc4 e6 5.Bb5 etc...

ça tient moins de place

Voilà, si quelqu'un a une piste....

@+

21 réponses

cs_philcam Messages postés 132 Date d'inscription dimanche 12 août 2001 Statut Membre Dernière intervention 17 octobre 2008
28 août 2005 à 16:01
Bon, finallement je me suis creusé la tête (j'avais la flemme aujourd'hui)

J'ai donc réalisé le truc avec une RichTextBox (RT)

Option Explicit

Private Sub Form_Load()
RT.LoadFile App.Path & "\test.pgn"

Dim I As Long
Dim Deb As Long
Dim Fin As Long

While Deb <> -1
Deb = RT.Find("{", I)
Fin = RT.Find("}", Deb)

If Deb <> -1 Then
RT.SelStart = Deb
RT.SelLength = Fin - Deb + 2
RT.SelRTF = ""
End If

I = Deb + 1
Wend

End Sub

C'était pas si compliqué, mais fallait se concentrer, et c'est une méthode rapide par rapport à prendre tous les caractères un par un (la RTbox le fait à notre place)

@++
3
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
28 août 2005 à 14:20
Ben le plus simple, c'est de rechercher la position de chaque { auquel
il y a un } correspondant, et de supprimer le tout. Tu peux le faire en
utilisant les fonction InStr (recherche dans une chaîne), et Mid
(récupèration d'une sous-chaîne à partir d'une chaîne, de la position
de départ, et de la longueur à récupèrer).

DarK Sidious

Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
0
ashboody Messages postés 91 Date d'inscription samedi 30 mars 2002 Statut Membre Dernière intervention 11 octobre 2005
28 août 2005 à 14:22
faire du parsage de texte en VB c'est pas forcément le plus rapide, mais une technique serait de tester chaque caractère successivement et de positionner un flag à 1 lorsque tu recontre une accolade { et de reseter se flag à 0 lorsque tu rencontre une accolage } afin de reprendre l'enregistrement du texte,
si mon algo a 2€ te conviens tant mieux

sur ce bonne continuation
0
cs_philcam Messages postés 132 Date d'inscription dimanche 12 août 2001 Statut Membre Dernière intervention 17 octobre 2008
28 août 2005 à 15:13
Oui, j'ai pensé à ce genre de méthode mais ça va être lourd à mettre en place....


J'avais pensé aussi à ouvrir le fichier dans une richtextbox pour pouvoir mieux sélectionner automatiquement chaque partie entre les guillemets et les supprimer ensuite, par contre je ne connais pas les méthodes pour faire ça, donc si quelqu'un connait bien les richtextbox et a une idée merci.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
28 août 2005 à 16:25
Ton code serait plus optimisé si tu avais utilisé les fonctions que je
t'ai donné ! Le code serait grosso-modo le même, sauf qu'à la place de
la fonction Find, il faut utiliser InStr, et au lieu de faire des
sélections comme tu le fait, il faudrait découper la chaîne du début à
la position de départ, et de la position de fin à la fin de la chaîne.



Avec ta méthode, il faut utiliser un RichTextBox (attention au
déploiement de l'application et les incompatibilités qui peuvent
apparaîtrent, notamment avec Win98 !!!) ce qui prend déjà bien plus de
ressources !

DarK Sidious

Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
0
cs_CanisLupus Messages postés 3757 Date d'inscription mardi 23 septembre 2003 Statut Membre Dernière intervention 13 mars 2006 21
28 août 2005 à 18:37
Salut, pour appuyer DARKSIDIOUS, un tit bout de code, sans parcours de la chaine et qui ressemble au tien (sans rtb) :

Dim s As String
Dim deb As Long
Dim lng As Long
Dim nFic As Integer


nFic = FreeFile


Open App.Path & "\test.pgn" For Input As #nFic
s = Input(LOF(nFic), #nFic)
Close #nFic


Do While InStr(s, "{") > 0
deb = InStr(s, "{")
lng = InStr(s, "}") + 2 - deb
s = Replace(s, Mid(s, deb, lng), "")
Loop


MsgBox s

Seule restriction, comme pour ton code, ça ne gère pas les accolades imbriquées. Je sais bien que, normalement, dans ce genre de notation ça ne doit pas arriver mais sait-on jamais ?

PS : interéressant cette variante de la Sicilienne fermée.

-------------------------------------------------
Dresseur de puces, .... normal pour un loup !?
0
cs_philcam Messages postés 132 Date d'inscription dimanche 12 août 2001 Statut Membre Dernière intervention 17 octobre 2008
29 août 2005 à 00:08
Salut,

j'essaye ton code, qui est en en train de tourner en ce moment et qui n'a pas fini son calcul pendant que j'écris.

Heureusement que j'ai supprimer la msgbox car j'imagine pas la gueule qu'elle aurait eu pour afficher des milliers de lignes
Et oui, car il y a 139 parties dans ce fichier et il pèse 931Ko.

Avec la richtextbox il met environ 15secondes (P4, 3Ghz) pour supprimer les commentaires, je sais c'est énorme mais pour l'instant c'est juste un programme pour moi, ça va qd même + vite qu'à la main

Sinon, merci pour votre aide, je vais creuser ces idées.

Merci et @+
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
29 août 2005 à 01:06
ça m'étonnerais !

c'est les "Replace" qui prennent du temps







Dim s As String

Dim c As String

Dim i As Integer

Dim j As Integer



s = "1.e4 {(e2e4) +0.02/99} c5 2.Nc3 {(Cb1c3)
+0.02/99} Nc6 3.g3 {(g2g3) +0.02/99} Nf6 {(Cg8f6 Cg1f3 d7d5 e4xd5
Cf6xd5 Ff1c4 e7e6 00 Ff8e7 d2d3) 0.00/10 1} 4.Bc4 {(Ff1c4 e7e6 Cg1f3
d7d5 e4xd5 e6xd5 Dd1e2+ Fc8e6) -0.14/7 4} e6 {(e7e6 d2d3 d7d5 Fc4b5
Fc8d7 Cg1f3 d5d4 Fb5xc6 Fd7xc6 Cc3e2) +0.25/10 2} 5.Bb5"



For i = 1 To Len(s)

c = Mid$(s, i, 1)

If c "{" Then j j + 1

If j > 0 Then Mid$(s, i, 1) = Chr$(164)

If c "}" Then j j - 1

Next

s = Replace(s, Chr$(164), "")

MsgBox s


Daniel
0
cs_philcam Messages postés 132 Date d'inscription dimanche 12 août 2001 Statut Membre Dernière intervention 17 octobre 2008
29 août 2005 à 17:41
Je suis désolé mais le fichier que je prends pour faire mes tests fait pas loin d'1Mo
Donc forcément ça prend du temps
de plus y a tellement de caractères à mettre dans "s" que 'integer' ne suffit pas, il me met "dépassement de capacité"
j'ai mis en "long" au lieu d'"integer", ça marche mais ça met + de 15 secondes.

où alors je suis
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
29 août 2005 à 17:46
s c'est la chaine, donc c'est pas limité en Longueur

i et j peuvent être remplacés par des Long



avec boucle d'attente 3507 fois 299 caractères soit 1048593 j'ai un temps total de 1,047 secondes.

et encore sans être compilé.

Daniel
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
29 août 2005 à 17:49
Et encore, tu fais des replace, si tu enlève les replace (remplacés par des Mid), ca doit être encore plus rapide !

DarK Sidious

Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
29 août 2005 à 18:31
Alors après quelques petites recherches, voici le verdict : avec ta
procédure, 7,5 s de temps de traitement avec un richtextbox non visible
en mde compilé (donc traitement bien optimisé) sur un fichier de 500 Ko.



Avec la procédure que je donne dessous, 3 s (toujours en mode compilé
sinon, c'est VB qui bride la rapidité, mais reste tout de même plus
rapide que le RTB sous mode interprêté) en utilisant uniquement les
fonctions InStr et Mid. Bon ma procédure n'est pas parfaite, il reste
encore quelques petites rectif à faire sûrement pour obtenir des
résultats fiables (je sais pas si dans ton fichier il y a des saut de
lignes par exemple qui empêche mon script de bien fonctionner), mais la
rapidité y est, et le résultat est bon sans saut de ligne.



Voici le code :



Dim sText As String

Dim sFinishText As String

Dim lPosition(3) As Long

Dim iFileNumber As Integer



Let iFileNumber = FreeFile

Open App.Path & "\test.pgn" For Input As #iFileNumber



While Not EOF(iFileNumber)



Line Input #iFileNumber, sText

Let lPosition(0) = InStr(1, sText, "{")

Let lPosition(1) = InStr(1, sText, "}")

Let lPosition(2) = lPosition(0)

Let lPosition(3) = lPosition(1)

If
lPosition(0) > 0 Then Let sFinishText = sFinishText &
Left(sText, lPosition(0) - 1)



While lPosition(0) > 0 And lPosition(1) > 0




Let lPosition(2) = InStr(lPosition(0) + 1, sText, "{")


Let lPosition(3) = InStr(lPosition(2) + 1, sText, "}")


If lPosition(2) > 0 And lPosition(3) > 0 Then Let sFinishText =
sFinishText & Mid(sText, lPosition(1) + 1, lPosition(2) -
lPosition(1) - 1)

Let lPosition(0) = lPosition(2)

Let lPosition(1) = lPosition(3)



Wend



Wend



Close #iFileNumber

DarK Sidious

Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
29 août 2005 à 18:34
j'ai qu'un seul Replace à la fin

je vais déjà plus vite en nom compilé.

et comme a dit CannisLupus les chaînes imbriquées sont traitées.

Daniel
0
cs_CanisLupus Messages postés 3757 Date d'inscription mardi 23 septembre 2003 Statut Membre Dernière intervention 13 mars 2006 21
29 août 2005 à 18:52
C'est vrai que le replace est pas très performant dans ce cas.
Et comme ça, avec parcours de la chaine ? :

For i = 1 To Len(s)
temp = Mid(s, i, 1)
Select Case temp
Case "{"
test = True
Case "}"
test = False
Case Else
If Not test Then s1 = s1 & temp
End Select
Next

MsgBox s1

Il risque d'y avoir des espaces en trop et il faudra faire un :
s1 = replace(s1," "," ")

Dans ce cas, c'est le s1 = s1 & temp qui prendra le plus de temps. A tester, je n'ai pas de fichier png de 1 Mo sous la main.

-------------------------------------------------
Dresseur de puces, .... normal pour un loup !?
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
29 août 2005 à 18:53
Tu es plus rapide ? Remplacer autant de Chr(164) sur un fichier de 500
Ko est plus rapide que jouer avec la fonction mid ? Je demande à voir
tout de même... ;)



C'est pour cette raison que j'ai comparé ton code avec le mien sur le
fichier de 500 Ko que j'ai reconstitué en collant plusieurs fois (pas
mal de fois quand même) ta ligne exemple.



Verdict ?

En mode compilé, richtextbox non visible : 7 s

En mode compilé, ton code : 7,5 s

En mode compilé, mon code : 2,5 s



Le replace sera toujours plus lent que plusieurs appel à Mid car il
doit rechercher la chaîne plusieurs fois et la remplacer par une
nouvelle sûrement !


DarK Sidious

Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
0
cs_CanisLupus Messages postés 3757 Date d'inscription mardi 23 septembre 2003 Statut Membre Dernière intervention 13 mars 2006 21
29 août 2005 à 18:57
AIe, quand j'ai posté, il n'y avait pas les posts de DARKSIDIOUS et de Daniel.

-------------------------------------------------
Dresseur de puces, .... normal pour un loup !?
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
29 août 2005 à 18:57
Désolé canis lupus, mais tu mérite la palme de la lenteur ;)



Avec ton code, il faut 9.5 secondes pour obtenir le même résultat (mode
compilé bien entendu), c'est donc le code le plus lent. Il ne faut pas
non plus appeler trop souvent la fonction Mid quand même, faut pas
exagérer lol.


Bon allez, il faut que j'arrête là, car c'est bien beau tout cà, mais mon boulot n'avance pas :(


DarK Sidious

Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
29 août 2005 à 18:58
c'est ce que je fais appel à Mid$

il est utilisé en tant que changement de caractères donc sans changement de longueur de chaîne.

mais comme je ne peux pas tester, n'ayant pas de fichier png,

le temps dépend fortement du nombre d'accolade { } dans le fichier

ça varie de 0,3 s à 11 s

Daniel
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
29 août 2005 à 19:09
Ce ne sont pas tes mid qui prennent du temps daniel, c'est ton replace
de fin qui prend beaucoup de temps à s'éxécuter car il y a beaucoup de
Chr(165) à remplacer au final !



Sans le replace final, tu tombe à 5 s => tu retombe sur le problème
de canis lupus : tu appelle trop souvent la fonction Mid en parcourant
toutes la chaîne et en testant tout les caractères !

DarK Sidious

Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
0
cs_CanisLupus Messages postés 3757 Date d'inscription mardi 23 septembre 2003 Statut Membre Dernière intervention 13 mars 2006 21
29 août 2005 à 20:38
lol, pour une fois que j'ai une palme, c'est celle de la lenteur !
Cela dit, je pense que c'est à notre ami philcam de choisir.

-------------------------------------------------
Dresseur de puces, .... normal pour un loup !?
0
Rejoignez-nous