Tramber Posté(e) le 18 novembre 2010 Posté(e) le 18 novembre 2010 Bonjour, (vl-string-trim "," ",0,0,0,,,") me permet d'obtenir "0,0,0".C'est un préalable utile. Dans ce vieux sujet, j'ai demandé de l'aide pour traiter le problème suivant : Soit une chaine de caractères, je veux en retirer tout ce qui n'est pas chiffre entier ou virgules qui les séparent. Le but étant, à terme, de transformer le tout en liste d'entiers. "1" renvoie "1""1,2" renvoie "1,2""_\oi-_,90,ut5," renvoie ",90,5," -> (vl-string-trim "," ",90,5,") à la fin rend facilement "90,5""123,,,51,2" renvoie "123,51,2" J'y arrive bien (et encore !) avec des routines lourdingues mais je me demande s'il n'y a pas de solutions récursives. Comme j'ai un peu le sujet en tête...On y parle de mécanique mais j'ai l'impression parfois de n'être qu'un chauffeur (si le lisp est le moteur) et ni ingénieur, ni même mécanicien :cool: Alors pourl'instant, j'essaie déjà un bon traitement non récursif : (defun test(nom / lettre compt) (setq compt 1) (while(and(>(strlen nom)0)( (if (wcmatch(setq lettre(substr nom compt 1)) "[0-9],[`,]") (setq compt(1+ compt)) (setq nom(vl-string-subst "" lettre nom)) )) nom) (test "3") (test "3,2") (test "3,2.") (test "..|_3,2.") (test "3,2,,,1") Seulement voilà, comme le montre le dernier test, je n'ai pas pu traiter efficacement les virgules en trop !Serait-ce un challenge intéressant d'aller plus loin, et avec une fonction récursive ? ou cela devient-il superflu ?Autre question, très liée je pense, si je devais éclater cette chaine d'entrée en autant d'éléments d'une liste constituée de caractères simples. La récursivité est mieux adaptée aux listes (!?), non ? Hop Bureau d'études dessin. Spécialiste Escaliers Développement - Formation ./__\. (.°=°.)
(gile) Posté(e) le 18 novembre 2010 Posté(e) le 18 novembre 2010 Vite fait, Si on veut vraiment faire du récursif, sur les chaînes c'est assez facile avec la concaténation mais le traitement des chaînes est en général assez couteux (defun test (nom / lettre) (if (= nom "") "" (if (wcmatch (setq lettre (substr nom 1 1)) "[0-9],`,") (strcat lettre (test (substr nom 2))) (test (substr nom 2)) ) ) ) On avait vu que le traitement des listes est plus rapide en LISP (defun toto (nom) (vl-list->string (vl-remove-if-not '(lambda (x) (or (= x 44) ( (vl-string->list nom) ) ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Tramber Posté(e) le 18 novembre 2010 Auteur Posté(e) le 18 novembre 2010 Je te remercie. et c'est vrai qu'avec vl-list->string et son pendant inverse, le passe-passe est facile. J'étudie cette piste histoire de supprimer les code 44 en doubles (les virgules). C'est mon ultime étape pour cette fonction.Mais j'avoue que je n'arrive pas à monter cet outil, exemple avec TOTO : (vl-remove-if '(lambda(x y)(= 44 x y))(vl-string->list "3,,4,5")) Ca n'est peut-être pas si simple. Bureau d'études dessin. Spécialiste Escaliers Développement - Formation ./__\. (.°=°.)
(gile) Posté(e) le 18 novembre 2010 Posté(e) le 18 novembre 2010 Si les chaînes ne sont pas trop longues, la différence de rapidité d'exécution entre une solution récursive et vl-remove-if devrait être quasiment insensible.On peut alors utiliser un drapeau (flag) qui indique si le dernier caractère ajouté était une virgule. (defun toto (str / foo) (defun foo (s f / c) (cond ((= s "") s) ((= (setq c (substr s 1 1)) ",") (strcat (if (= f 1) "" c) (foo (substr s 2) 1)) ) ((wcmatch c "[0-9]") (strcat c (foo (substr s 2) 0))) ((foo (substr s 2) f)) ) ) (foo str 0) ) Si tu veux supprimer les virgules à la fin, remplace ((= s "") "") par ((or (= "," s) (= s "") "")Si tu veux supprimer les virgules au début remplace (foo str 0) pat (foo str 1) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 18 novembre 2010 Posté(e) le 18 novembre 2010 ou itératif : (defun toto (str / flag rslt char) (setq flag 0 rslt "" ) (while (/= str "") (cond ((= (setq char (substr str 1 1)) ",") (if (= flag 0) (setq rslt (strcat rslt ",") flag 1 ) ) ) ((wcmatch char "[0-9]") (setq rslt (strcat rslt char) flag 0 ) ) ) (setq str (substr str 2)) ) rslt ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Tramber Posté(e) le 18 novembre 2010 Auteur Posté(e) le 18 novembre 2010 Joli ! Tout marche bien. Même en itératif, cela montre que j'aurais pu faire mieux moi-même. (vl-string-trim "," ",0,0,0,,,") me permet d'obtenir "0,0,0".donc je ne me fais pas de bile pour les virgules avant ou après ! Je passe ce traitement au moment opportun. Hoppla Bureau d'études dessin. Spécialiste Escaliers Développement - Formation ./__\. (.°=°.)
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant