DenisHen Posté(e) le 29 janvier 2022 Posté(e) le 29 janvier 2022 Bonjour à la communauté. Voilà, je dois trouver le chiffre unique contenu dans une chaine, par exemple, dans "Ma80cm", j'aimerais isolé 80. Si quelqu'un a une astuce, un bout de code, une idée... Je suis preneur... Bien à toi la communauté. Denis... Windows 11 / AutoCAD 2024 Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net). Davantage d'avantages, avantagent davantage (Bobby Lapointe). La connaissance s'accroît quand on la partage (Socrate). Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)
(gile) Posté(e) le 29 janvier 2022 Posté(e) le 29 janvier 2022 Donc, tant que le premier caractère de la chaine en entrée n'est pas un chiffre, on supprime le premier caractère de la chaine en entrée. Puis, tant que le premier caractère de la chaîne de la chaine en entrée est un chiffre, on ajoute ce caractère à la fin de la chaîne en sortie et on supprime le premier caractère de la chaine en entrée. Voir les fonctions : while, substr, wcmatch, et strcat. Ou, plus efficient, traiter les chaînes comme des listes de caractère ascii (nombres entiers en LISP). Voir les fonctions vl-string->list, vl-list->string et les fondamentales car, cdr et cons. Ou encore, si la chaîne ne contient qu'un nombre, plus concis et élégant avec : vl-string->list, vl-list->string, vl-remove-if-not et lambda. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
JPhil Posté(e) le 29 janvier 2022 Posté(e) le 29 janvier 2022 Test chaque caractère de la chaîne un par un, et si il y a un chiffre le met dans la variable strnb. (Setq chaîne "Ma80cm") (Setq I 0) (Setq strnb nil) (while (< (length chaîne) I) (if (= (wcmatch (itoa (substr chaîne I 1)) "[0-9]") T) (Setq strnb (strcat strnb (substr chaîne I 1))) ) (Setq I (+ I 1)) ) (Princ strnb) [Edit] je viens de voir qu'il manquait une parenthèse à la fin de "(setq strnb (strcat ...", erreur résolue.
bonuscad Posté(e) le 30 janvier 2022 Posté(e) le 30 janvier 2022 Comme l'a suggéré (gile) avec les fonctions (vl-*** Seul bémol si le caractère "." ou "-" se trouve n'importe où dans la chaîne, cela peut donner un résultat erroné! (defun extract_num4str (str / ) (atof (vl-list->string (vl-remove-if '(lambda (x) (or (< x 45) (> x 57))) (vl-string->list str)))) ) Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
DenisHen Posté(e) le 30 janvier 2022 Auteur Posté(e) le 30 janvier 2022 Bonjour à la communauté et merci à vous pour votre aide. @(gile): j'ai bien saisis ton idée, mais je ne sais pas si j'y serais arrivé seul, j'ai encore un peu de mal avec wcmatch et je ne maitrise pas les vl-* et encore moins lambda. @JPhil : ton code m'a permis de mieux appréhender les autres messages. @bonuscad : ton code me convient parfaitement. Encore merci à vous et à la communauté. Denis... Windows 11 / AutoCAD 2024 Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net). Davantage d'avantages, avantagent davantage (Bobby Lapointe). La connaissance s'accroît quand on la partage (Socrate). Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)
(gile) Posté(e) le 30 janvier 2022 Posté(e) le 30 janvier 2022 Il y a 10 heures, (gile) a dit : tant que le premier caractère de la chaine en entrée n'est pas un chiffre, on supprime le premier caractère de la chaine en entrée. Puis, tant que le premier caractère de la chaîne de la chaine en entrée est un chiffre, on ajoute ce caractère à la fin de la chaîne en sortie et on supprime le premier caractère de la chaine en entrée. (defun fun1 (input / output) (while (not (wcmatch (substr input 1 1) "#")) (setq input (substr input 2)) ) (setq output "") (while (wcmatch (substr input 1 1) "#") (setq output (strcat output (substr input 1 1)) input (substr input 2) ) ) output ) Il y a 10 heures, (gile) a dit : Ou, plus efficient, traiter les chaînes comme des listes de caractère ascii (nombres entiers en LISP) (defun fun2 (str / lst res) (setq lst (vl-string->list str)) (while (and lst (not (< 47 (car lst) 58))) (setq lst (cdr lst)) ) (while (and lst (< 47 (car lst) 58)) (setq res (cons (car lst) res) lst (cdr lst) ) ) (vl-list->string (reverse res)) ) Il y a 10 heures, (gile) a dit : Ou encore, si la chaîne ne contient qu'un nombre, plus concis et élégant (defun fun3 (str) (vl-list->string (vl-remove-if-not '(lambda (c) (< 47 c 58)) (vl-string->list str) ) ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
JPhil Posté(e) le 30 janvier 2022 Posté(e) le 30 janvier 2022 C'est dans ce genre d'exercice où l'on voit que chacun a une approche différente de la résolution du problème, et ça c'est plutôt intéressant. Et toi @DenisHen, quelle approche avais-tu en tête ?
DenisHen Posté(e) le 30 janvier 2022 Auteur Posté(e) le 30 janvier 2022 @JPhil, j'avais à peu près la même approche que toi, mais je ne m'en serais jamais sorti avec (wcmatch (itoa (substr chaîne I 1)) "[0-9]"). Windows 11 / AutoCAD 2024 Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net). Davantage d'avantages, avantagent davantage (Bobby Lapointe). La connaissance s'accroît quand on la partage (Socrate). Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)
JPhil Posté(e) le 30 janvier 2022 Posté(e) le 30 janvier 2022 Tous les chemins mènent à Rome ;) Aurais-tu une idée afin d'extraire uniquement les caractères minuscules de la chaîne "Ma80cm" ? Et quitte à faire l'exercice jusqu'au bout, extraire uniquement les caractères majuscules. On peut aussi rajouter en bonus le grand défis des caractères accentués.
DenisHen Posté(e) le 30 janvier 2022 Auteur Posté(e) le 30 janvier 2022 Peut-être avec (wcmatch (itoa (substr chaîne I 1)) "[a-z]") ? Windows 11 / AutoCAD 2024 Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net). Davantage d'avantages, avantagent davantage (Bobby Lapointe). La connaissance s'accroît quand on la partage (Socrate). Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)
JPhil Posté(e) le 30 janvier 2022 Posté(e) le 30 janvier 2022 Pas bête (faut penser à virer itoa par contre car c'est pour les chiffres), perso j'avais en tête d'utiliser strcase afin de voir si le caractère était en majuscule ou pas, et un mélange de strcase et xstrcase pour les caractères accentués.
DenisHen Posté(e) le 30 janvier 2022 Auteur Posté(e) le 30 janvier 2022 Suite à ma consultation du magnifique "Introduction a AutoLISP" de notre ami (gile) et au site "da-code" de notre ami didier, peut-être ceci : (wcmatch (substr chaîne I 1) "[a-z,éèçàâäêëûüîï]") (je viens juste de remarquer que toutes les voyelles étaient sur la première ligne du clavier...). Attention, je n'ai rien testé, c'est juste une idée... Windows 11 / AutoCAD 2024 Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net). Davantage d'avantages, avantagent davantage (Bobby Lapointe). La connaissance s'accroît quand on la partage (Socrate). Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)
JPhil Posté(e) le 30 janvier 2022 Posté(e) le 30 janvier 2022 Pas testé non plus, mais je vois plus ça : (wcmatch (substr chaîne I 1) "[a-z],ç,à,â,ä,á,ã,å,ā,ă,ą,ê,ë,é,è,ē,ė,ę,ě,ĕ,ə,î,ï,í,ì,ı,į,ī,ó,ò,ô,ö,õ,ő,ü,ú,ù,û,ų,ű,ů,ū") Fait à partir d'une tablette sous Android
Luna Posté(e) le 30 janvier 2022 Posté(e) le 30 janvier 2022 Coucou, J'avais déjà une fonction en stock pour chat 🙂 ; []-----------------------[] Wildcard-trim []-----------------------[] ; ;--- Date of creation > 10/12/2021 ; ;--- Last modification date > 10/12/2021 ; ;--- Author > Luna ; ;--- Version > 1.0.0 ; ;--- Class > "BaStr" ; ;--- Goal and utility of the main function ; ; When used for functions (vl-string-*-trim), lists all the characters corresponding to the specified pattern in the form of a list from the 256 ; ; characters present in the ASCII table. ; ; ; ;--- Declaration of the arguments ; ; The function (Wildcard-trim) have 1 argument(s) : ; ; --• w > correspond to the pattern that each character needs to match ; ; (type w) = 'STR | Ex. : "#", "@", "~#", ".,#", ... ; ; ; ;--- Return ; ; The function (Wildcard-trim) returns a list of characters (1 single character per string) whose characteristics correspond to the wildcard ; ; specified in argument (see wcmatch for the Wild-Card Characters). ; ; Ex. : (Wildcard-trim "#") returns ("0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "²" "³" "¹") ; ; (Wildcard-trim "@") returns ("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" ; ; "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" ; ; "ƒ" "Š" "Œ" "Ž" "š" "œ" "ž" "Ÿ" "ª" "µ" "º" "À" "Á" "Â" "Ã" "Ä" "Å" "Æ" "Ç" "È" "É" "Ê" "Ë" "Ì" "Í" "Î" ; ; "Ï" "Ð" "Ñ" "Ò" "Ó" "Ô" "Õ" "Ö" "Ø" "Ù" "Ú" "Û" "Ü" "Ý" "Þ" "ß" "à" "á" "â" "ã" "ä" "å" "æ" "ç" "è" "é" ; ; "ê" "ë" "ì" "í" "î" "ï" "ð" "ñ" "ò" "ó" "ô" "õ" "ö" "ø" "ù" "ú" "û" "ü" "ý" "þ" "ÿ") ; ; ; ;--- Historic list of the version with their modification status ; ; +------------+----------------------------------------------------------------------------------------------------------------------------------+ ; ; | v1.0.0 | Creation of the function | ; ; +------------+----------------------------------------------------------------------------------------------------------------------------------+ ; ; ; (defun wildcard-trim (w / i lst a) (repeat (setq i 256) (if (wcmatch (setq a (chr (setq i (1- i)))) w) (setq lst (cons a lst)) ) ) lst ) Du coup pour répondre au challenge, je donnerai cette version : (vl-string-trim (apply 'strcat (wildcard-trim "~#")) str) Évidemment, avec la fonction (vl-string-trim) cela permet uniquement de supprimer les caractères en partant de la gauche et de la droite, jusqu'à ce qu'un caractère autorisé soit trouvé. Autrement dit, pour une chaîne de caractère telle que (setq str "ma80cm") ;; ou (setq str "Surface = 42.23m (+NGF)") ;; etc... On obtient respectivement les résultats : "80" ;; ou "42.23" Mais comme le souligne @bonuscad, dans le cas d'un nombre négatif, le moins est supprimé donc il y a une perte d'information dans ce cas-ci. Autre limite : dans le cas où il y a deux valeurs numériques dans une même chaîne de caractères, comme par exemple (setq str "Value = -543.1530054 (equals to 2u)") (vl-string-trim (apply 'strcat (wildcard-trim "~#")) str) returns "543.1530054 (equals to 2" Bref, cela réponds à un problème simple dans les conditions établies, mais cela possède ses propres limites tout de même si l'on étend son utilisation en dehors des conditions actuelles. Par contre, les nombres décimaux sont conservés correctement 😉 Bisous, Luna
(gile) Posté(e) le 31 janvier 2022 Posté(e) le 31 janvier 2022 Pour capturer un ou plusieurs nombres, entiers ou réels, négatifs ou positifs, j'utiliserais les expressions régulières. (defun getFirstNumber (str) (caar (RegExpExecute str "(-?\\d+(?:\\.\\d+)?)" nil nil)) ) (defun getAllNumbers (str) (mapcar 'car (RegExpExecute str "(-?\\d+(?:\\.\\d+)?)" nil T)) ) _$ (getFirstNumber "Ma80cm") "80" _$ (getFirstNumber "Surface = 42.23m (+NGF)") "42.23" _$ (getAllNumbers "Surface = 42.23m² Température = -4°C") ("42.23" "-4") Petite explication du motif (pattern) utilisé : ( début de groupe capturé -? zero ou un - \\d+ un ou plusieurs chiffres (?: début de groupe non capturé \\.\\d+ un point suivi de un ou plusieurs chiffres ) fin de groupe non capturé ? zero ou un groupe ) fin de groupe capturé 1 Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Luna Posté(e) le 31 janvier 2022 Posté(e) le 31 janvier 2022 J'avais en effet supposé que les expressions régulières seraient parfaite pour faire ce genre de travail !! Mais comme je n'ai toujours pas eut le temps d'étudier le sujet, je ne les maîtrise pas (notamment à cause des caractères de recherche qui diffèrent des WildCard Characters donc mon cerveau n'est pas encore suffisamment habitué)... Mais il va sérieusement falloir que je passe du temps à étudier toutes ces notions encore un peu trop obscures à mes yeux, parce que j'ai l'impression de faire du surplace en programmation pour le moment et j'aime pas trop chat... Merci pour cet exemple @(gile) ! Bisous, Luna
lecrabe Posté(e) le 31 janvier 2022 Posté(e) le 31 janvier 2022 Hello @(gile) Bravo tu es regulierement competent ! La Sante, Meilleurs Voeux, Bye, lecrabe Autodesk Expert Elite Team
JPhil Posté(e) le 31 janvier 2022 Posté(e) le 31 janvier 2022 Autre solution possible de la part d'un développeur fainéant : 1) afficher la chaine de caractère "Ma80cm" 2) demander à l'utilisateur les caractères qu'il veut isoler 3) vérifier avec wcmatch, si ok étape 4 sinon retour étape 1 4) suite du programme On a bien dit que tous les chemins mènent à Rome, non ? 😇
VDH-Bruno Posté(e) le 31 janvier 2022 Posté(e) le 31 janvier 2022 Le 29/01/2022 à 18:46, DenisHen a dit : Bonjour à la communauté. Voilà, je dois trouver le chiffre unique contenu dans une chaine, par exemple, dans "Ma80cm", j'aimerais isolé 80. Si quelqu'un a une astuce, un bout de code, une idée... Je suis preneur... Bien à toi la communauté. Denis... Bonjour, Si tu es sur que ta chaîne ne contient que des caractères AlphaNumérique, tu peux très simplement tenter ceci: _$ (vl-string-trim "ABCDEFGHIJKLMNOPQRSTUVWXYZ" (strcase "Ma80cm")) "80" _$ (vl-string-trim "ABCDEFGHIJKLMNOPQRSTUVWXYZ" (strcase "80Macm")) "80" _$ (vl-string-trim "ABCDEFGHIJKLMNOPQRSTUVWXYZ" (strcase "Macm80")) "80" Cdt Bruno (Ps: Sinon il y a évidement les expressions régulières mentionné par (gile) beaucoup plus puissante..) Apprendre => Prendre => Rendre
VDH-Bruno Posté(e) le 31 janvier 2022 Posté(e) le 31 janvier 2022 Le 29/01/2022 à 21:39, (gile) a dit : Donc, tant que le premier caractère de la chaine en entrée n'est pas un chiffre, on supprime le premier caractère de la chaine en entrée. Puis, tant que le premier caractère de la chaîne de la chaine en entrée est un chiffre, on ajoute ce caractère à la fin de la chaîne en sortie et on supprime le premier caractère de la chaine en entrée. Et pour le jeu en traduisant récursivement l’algorithme donné par (gile), ça peut donner ceci: (defun f (s) (cond ((= s "") "") ((wcmatch (substr s 1 1) "#") (strcat (substr s 1 1) (f (substr s 2)))) (T (f (substr s 2))) ) ) Apprendre => Prendre => Rendre
(gile) Posté(e) le 31 janvier 2022 Posté(e) le 31 janvier 2022 Il y a 2 heures, VDH-Bruno a dit : Et pour le jeu en traduisant récursivement l’algorithme donné par (gile), ça peut donner ceci: Pas tout à fait, je disais "Puis, tant que le premier caractère ..." et ta routine évalue toute la chaîne même si les derniers caractères ne sont pas de chiffres. On pourrait utiliser un argument à T ou nil pour s'arrêter au dernier chiffre trouvé: (defun f (s p) (cond ((= s "") "") ((wcmatch (substr s 1 1) "#") (strcat (substr s 1 1) (f (substr s 2) T))) (p "") (T (f (substr s 2) p)) ) ) _$ (f "Ma80cm" nil) "80" Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
VDH-Bruno Posté(e) le 31 janvier 2022 Posté(e) le 31 janvier 2022 il y a une heure, (gile) a dit : Pas tout à fait, je disais "Puis, tant que le premier caractère ..." et ta routine évalue toute la chaîne même si les derniers caractères ne sont pas de chiffres. Oui tu as raison, je me suis fait prendre par la patrouille, en première intention je voulais écrire une fonction auxiliaire pour ne pas parcourir toute la chaîne, puis comme c'était à titre d'exemple j'ai sacrifié l'efficience à la concision pensant que personne ne le verrais... 😂 il y a une heure, (gile) a dit : Il y a 3 heures, VDH-Bruno a dit : Et pour le jeu en traduisant récursivement l’algorithme donné par (gile), ça peut donner ceci: D’ailleurs comme j'avais mauvaise conscience, j'ai voulu me dédouaner en précisant "ça peut donner"😂😂😂 Oui il y avait une petite escroquerie, je te remercie de l'avoir relevée😉 Apprendre => Prendre => Rendre
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