[R] Découper une chaine de caractère "x" critères

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Avatar du membre
corrs78
Niveau 5
Niveau 5
Messages : 160
Enregistré le : lun. 13 août 2007 17:38
Localisation : Yvelines
Status : Hors ligne

[R] Découper une chaine de caractère "x" critères

#1

Message par corrs78 »

Bonjour à tous,
je sollicite votre aide, car je suis bloqué sur la conception d'un logiciel professionnel.
Ce logiciel est une petite BDD sqlite autonome.
J'ai créé un module d'impression grâce à l'excellent UDB PrintMGv2.au3
Cependant cette librairie n'est pas complète. Elle permet de générer directement une impression selon des coordonnées. On peut donc facilement imprimer du texte au km, ou alors des images, lignes, rectangles...etc

Mais j'ai un problème, lorsque je souhaite imprimer du texte, je n'arrive pas délimiter cette zone de texte.

Clairement, je dois découper ma chaine en fonction de la largeur de la page.

J'ai donc besoin de votre aide pour écrire une fonction qui decoupe une chaine de caractère (issue d'un TextEdit) en fonction du nombre de caractères et des « retours chariots »(@CRLF) insérés.

J'arrive à obtenir :
le nombre de caractères → StringLen()
la largeur de mon texte (en mm) → _PrintGetTextWidth
splitter en fonction des « retours chariots » → StringSplit($arme_divers, @CRLF, 1)

modélisation du problème :

SI string > 100 caractères ALORS couper la chaine afin qu'elle ne dépasse pas 100 caractères
SI string contient @CRLF ALORS couper la chaine
(pour l'instant je me moque qu'un mot soit coupé en deux, car c'est déjà assez compliqué pour moi :oops: )

mais j'ai beaucoup de mal à ordonner ces deux fonctions pour qu'elles fonctionnent ensemble
(arraydisplay)


Merci d'avance pour votre aide.

voilà ce que l'on a pondu avec un ami, mais ça fonctionne pas complètement:
installez une imprimante virtuelle comme DoPDF ou PDFCreator pour tester le rendu lors de l’exécution du script
► Afficher le texte
Fichiers joints
PrintMG.zip
UDF PrintMG
(244.57 Kio) Téléchargé 70 fois
Modifié en dernier par corrs78 le dim. 15 juil. 2012 23:47, modifié 1 fois.
Avatar du membre
Iste
Niveau 11
Niveau 11
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

Re: [..]Decouper une chaine de caractère "x" critères

#2

Message par Iste »

Si vous devez vraiment couper a x caractères (qu'ils font tous la meme taille donc) vous pouvez utiliser une solution du genre :

Code : Tout sélectionner

ClipPut(addCRLF(createLongString(), 100))

Func addCRLF(Const $string, Const $size)
    Return StringRegExpReplace($string, "(.{0,"&$size&"}\s)", "$1" & @CRLF)
EndFunc

Func createLongString()
    Local $longueChaine = ""

    For $i = 0 To 1000
        $mot = ""
        $rand = Random(2, 9, 1)
        For $j = 1 To $rand
            $mot &= Chr(97 + Random(0,25))
;~          $mot &= $rand
        Next
        $longueChaine &= $mot & " "
    Next

    return $longueChaine
EndFunc
La fonction addCRLF() ajoute des @crlf tout les x caractère en prenant soin de pas couper les mots
Signez ici
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..]Decouper une chaine de caractère "x" critères

#3

Message par mikell »

Est-ce que ça pourrait faire l'affaire ?

Code : Tout sélectionner

;SI string > 100 caractères ALORS couper la chaine afin qu'elle ne dépasse pas 100 caractères
;SI string contient @CRLF ALORS couper la chaine 

#Include <Array.au3>

$txt = "Ce logiciel est une petite BDD sqlite autonome." &@crlf& "J'ai créé un module d'impression grâce à l'excellent UDB PrintMGv2.au3" &@crlf& "Cependant cette librairie n'est pas complète. Elle permet de générer directement une impression selon des coordonnées. On peut donc facilement imprimer du texte au km, ou alors des images, lignes, rectangles...etc"

$res = StringRegExp($txt, '[^\r\n]{3,100}' , 3)
_ArrayDisplay($res)
Pour couper la ligne "proprement" (pas au milieu d'un mot) je vois guère que ça

Code : Tout sélectionner

$res = StringRegExp($txt, '[^\r\n]{3,86}[^\s]{0,14}' , 3)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Iste
Niveau 11
Niveau 11
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

Re: [..]Decouper une chaine de caractère "x" critères

#4

Message par Iste »

"[^\r\n]" = "." tant qu'on lève pas "(?s)"
[^\s] = \S

Mais au final ca fait quand même des lignes vides quand elles sont déjà assez courte, j'ai essayer de résoudre ce souci mais ca m'a prit la tête et j'ai mieux a faire ^^'
Signez ici
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..]Decouper une chaine de caractère "x" critères

#5

Message par mikell »

:shock: tu récupères des lignes vides avec ce script ?

Code : Tout sélectionner

#Include <Array.au3>
$txt = "Ce logiciel est une petite BDD sqlite autonome." &@crlf &@crlf&  "J'ai créé un module d'impression grâce à l'excellent UDB PrintMGv2.au3" &@crlf& "Cependant cette librairie n'est pas complète. Elle permet de générer directement une impression selon des coordonnées. On peut donc facilement imprimer du texte au km, ou alors des images, lignes, rectangles...etc"

_ArrayDisplay(_decoupe($txt, 86, 100) )

Func _decoupe($texte, $min, $max) 
   Return StringRegExp($texte, '(?s)[^\r\n]{3,' & $min & '}\S{0,' & $max-$min & '}' , 3)
EndFunc
(petite fatigue sur le \S ... ) :mrgreen:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Iste
Niveau 11
Niveau 11
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

Re: [..]Decouper une chaine de caractère "x" critères

#6

Message par Iste »

pourquoi "(?s)[^\r\n]" ? "." suffit
mikell a écrit ::shock: tu récupères des lignes vides avec ce script ?
Baheu nan... je sais pas ce que j'avais merdé en testant :/
Par contre

Code : Tout sélectionner

_ArrayDisplay(_decoupe($txt, 86, 100) )
nan nan,, c'est du const byref :P

Edit : "pourquoi "(?s)[^\r\n]" ? "." suffit" Bah non, c'est la que j'avais merdé, comprend pas, fatigué :(
Signez ici
Avatar du membre
corrs78
Niveau 5
Niveau 5
Messages : 160
Enregistré le : lun. 13 août 2007 17:38
Localisation : Yvelines
Status : Hors ligne

[..]Decouper une chaine de caractère "x" critères

#7

Message par corrs78 »

Je teste tout ça tout à l'heure ou demain matin, merci pour votre réactivité. Je n'avais pas du tout pensé aux expReg.
Avatar du membre
corrs78
Niveau 5
Niveau 5
Messages : 160
Enregistré le : lun. 13 août 2007 17:38
Localisation : Yvelines
Status : Hors ligne

Re: [..]Decouper une chaine de caractère "x" critères

#8

Message par corrs78 »

Code : Tout sélectionner

$res = StringRegExp($txt, '[^\r\n]{3,86}[^\s]{0,14}' , 3)
Merci à tous, et merci particulier à Mikell car cette version fonctionne très bien. je vais intégrer cela dans mon programme pour voir si cela fonctionne toujours aussi bien.

Quant à la dernière version, comme le dit Iste, il y a un soucis : (mais là ça me dépasse)
ERROR: _ArrayDisplay() called with expression on Const ByRef-param(s).
Avatar du membre
Iste
Niveau 11
Niveau 11
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

Re: [..]Decouper une chaine de caractère "x" critères

#9

Message par Iste »

On a juste pas le droit de passer directement un retour dans ces cas là

Code : Tout sélectionner

#Include <Array.au3>
$txt = "Ce logiciel est une petite BDD sqlite autonome." &@crlf &@crlf&  "J'ai créé un module d'impression grâce à l'excellent UDB PrintMGv2.au3" &@crlf& "Cependant cette librairie n'est pas complète. Elle permet de générer directement une impression selon des coordonnées. On peut donc facilement imprimer du texte au km, ou alors des images, lignes, rectangles...etc"

$var = _decoupe($txt, 86, 100)
_ArrayDisplay($var)

Func _decoupe($texte, $min, $max)
   Return StringRegExp($texte, '(?s)[^\r\n]{3,' & $min & '}\S{0,' & $max-$min & '}' , 3)
EndFunc
Signez ici
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..]Decouper une chaine de caractère "x" critères

#10

Message par mikell »

Je demande l'indulgence de l'assistance publique pour cette erreur de déclaration de variables dans ce qui n'était qu'un script de test destiné surtout à vérifier le regexp :oops:
Cela dit il me semble que cette fonction _decoupe() reste tout à fait intégrable dans un script sérieux, elle a l'avantage de rendre le regex paramétrable avec la possibilité de définir la quantité min et max de caractères (hors @crlf) que doivent contenir les lignes (en cas de changement de format d'impression, par exemple)
Iste ton avis ?

Code : Tout sélectionner

$var = _decoupe($txt, 86, 100)
_ArrayDisplay($var)
c'est ok ça non ?
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Iste
Niveau 11
Niveau 11
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

Re: [..]Decouper une chaine de caractère "x" critères

#11

Message par Iste »

Baheu, comme je l'ai donné juste avant oui c'est ok.
Mais pour que _decoupe() soit une vrai fonction bien conçue, il faudrait rajouter une gestion des erreurs au moins.
Mais faudrait revoir le param $min, je pense qu'on pourrait (devrait) s'en passer, mais je suis trop sûr de rien.
Sinon ca marche sans probleme !
Signez ici
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..]Decouper une chaine de caractère "x" critères

#12

Message par mikell »

Bof oui, de toute façon fonction ou pas, faudra bien la faire pour le regex la gestion d'erreurs ^^
Pour le param $min, on peut effectivement s'en passer mais alors il faut mettre dans le regex un équivalent ($max-14), sinon la découpe en fin de ligne pose problème

Code : Tout sélectionner

Func _decoupe($texte, $max)
   Return StringRegExp($texte, '(?s)[^\r\n]{3,' & $max-14 & '}\S{0,'14'}' , 3)
EndFunc
Mais on perd un peu de souplesse avec un param de moins
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Iste
Niveau 11
Niveau 11
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

Re: [..] Découper une chaine de caractère "x" critères

#13

Message par Iste »

Bah c'est que je vois pas du tout son intérêt, a par de couper les mots trop longs qui auraient la malchance de se trouver en fin de ligne.

Et la gestion des erreurs d'une regexp et d'une fonction _decoupe() ne sont pas du tout les même.
On est un niveau plus haut, donc on gère des erreurs un niveau plus haut aussi.
Signez ici
Avatar du membre
corrs78
Niveau 5
Niveau 5
Messages : 160
Enregistré le : lun. 13 août 2007 17:38
Localisation : Yvelines
Status : Hors ligne

[..] Découper une chaine de caractère "x" critères

#14

Message par corrs78 »

Pour ma part, vous avez entièrement résolu le problème. Mission accomplie ! Et encore bravo.
Merci pour votre célérité messieurs.

Ps: vous avez du rire en voyant mon exemple. Pourquoi faire simple quand on peut faire compliqué ;-)
Cela dit j'ai toujours autant de mal à déchiffrer les ExpReg.
Avatar du membre
corrs78
Niveau 5
Niveau 5
Messages : 160
Enregistré le : lun. 13 août 2007 17:38
Localisation : Yvelines
Status : Hors ligne

Re: [..] Découper une chaine de caractère "x" critères

#15

Message par corrs78 »

Petit détail, j'ai remarqué que lorsque le dernier caractère est un espace, j'ai un décalage de "1" caractère sur la ligne suivante.

exemple : (décalage représenté ici par " _ ")

Je suis en train de taper plusieurs lignes.
Ligne 2 -> ceci est la ligne 2
Ligne 3 -> on continu à taper au km pour créer un grande ligne et on voit ce que ça donne.
_Alors maintenant on retourne à la ligne.
ligne 4 -> voilà c'est terminé.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Découper une chaine de caractère "x" critères

#16

Message par mikell »

Petit détail oublié, sorry ^^
Effectivement il faut ajouter un \S en tête du pattern

Code : Tout sélectionner

Func _decoupe($texte, $min, $max)
   Return StringRegExp($texte, '(?s)[b]\S[/b][^\r\n]{3,' & $min & '}\S{0,' & $max-$min & '}' , 3)
EndFunc
PS : héhé, Iste toi non plus tu l'avais pas vu sui-là :P
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
corrs78
Niveau 5
Niveau 5
Messages : 160
Enregistré le : lun. 13 août 2007 17:38
Localisation : Yvelines
Status : Hors ligne

Re: [R] Découper une chaine de caractère "x" critères

#17

Message par corrs78 »

mikell a écrit :Petit détail oublié, sorry ^^
Effectivement il faut ajouter un \S en tête du pattern

Code : Tout sélectionner

Func _decoupe($texte, $min, $max)
   Return StringRegExp($texte, '(?s)[b]\S[/b][^\r\n]{3,' & $min & '}\S{0,' & $max-$min & '}' , 3)
EndFunc
PS : héhé, Iste toi non plus tu l'avais pas vu sui-là :P
J'ai essayé de modifier l'ExpReg, mais j'avais mis (?x) et ça ne fonctionnait pas.(car je n'ai pas compris la philosophie des Expreg)
Ensuite je suis arrivé à mes fins avec StringStripWS($var[$i],1) dans ma boucle.

Mais au final je vais prendre ta solution qui me permet de supprimer quelques lignes de code.

problème Résolu. Encore Merci.
Répondre