Hey_Its_Sanka Posté(e) le 22 octobre 2023 Posté(e) le 22 octobre 2023 Bonjour ! Voici mon problème : J'ai pleins de chaînes différentes où récupérer un réel. Existe-t-il une fonction Autolisp miracle ? Subtr ne correspond pas à ma problématique car oblige à définir un positionnement/longueur précis du réel à récupérer. (Pour info mes réels varient entre 0 et 199 et leur décimales sont toujours séparés par des points.) J'ai bien évidement chercher longuement sans trouver une réponse idéale, donc je vous demande de l'aide. Mon rêve : ✨ (Miracle "Blabla1.00") ---> 1.00 (Miracle "Blabla:123.45") ---> 123.45 (Miracle "Blabla 10.00Blabla") ---> 10.00 Si aucune fonction n'existe, je prend tout de même un code de secours... Merci ! 😄 PS : Pour les petit(e)s curieux/ses, mon programme consiste à cliquer un point (pour sa valeur en x) et un texte/bloc avec attribut depuis un plan topo (pour sa valeur d'altitude écrite) et finalement créer une polyligne avec la liste de points créé et hachures de TN en vue de façade. Je veux seulement pouvoir traiter n’importe quel texte du moment qu'il contient un réel (l'altitude) car ces derniers peuvent être écrits de diverses façons, selon le dessinateur du plan topo et la particularité du texte.
Hey_Its_Sanka Posté(e) le 22 octobre 2023 Auteur Posté(e) le 22 octobre 2023 Update : j'ai réussi à faire sans la fonction avec ça : (mais si vous avez une fonction qui le fait déjà, je suis prenneur !) (progn (setq w nil) (setq compteurdebut 1) (while (= (atof (substr txty compteurdebut 1) ) 0.0) (setq compteurdebut (1+ compteurdebut) ) ) (setq compteurfin compteurdebut) (while (and (/= compteurfin (strlen txty) ) (or (wcmatch (substr txty compteurfin 1) "*#*") (= (substr txty compteurfin 1) ".") ) (not w) ) (if (= (substr txty compteurfin 1) ".") (setq w 1) ) (setq compteurfin (1+ compteurfin) ) ) (while (and (/= compteurfin (strlen txty) ) (wcmatch (substr txty compteurfin 1) "*#*") ) (setq compteurfin (1+ compteurfin) ) ) (setq y (atof(substr txty compteurdebut (- (1+ compteurfin) compteurdebut) ) ) ) (setq pt (list x y)) ;point final )
(gile) Posté(e) le 22 octobre 2023 Posté(e) le 22 octobre 2023 Salut, Avec les expressions régulières. (defun miracle (str) (atof (caar (RegexpExecute str "(-?\\d+(?:\\.\\d+)?)" nil nil)) ) ) Ou avec deux fonctions récursives une fonction récursive. (defun miracle (str / loop) (defun loop (lst flag) (cond ((null lst) nil) ((< 47 (car lst) 58) (cons (car lst) (loop (cdr lst) (logior flag 1))) ) ((and (= 46 (car lst)) (/= 0 flag) ) (if (= flag 1) (cons 46 (loop (cdr lst) 3)) ) ) ((= flag 0) (loop (cdr lst) 0) ) (T nil) ) ) (distof (vl-list->string (loop (vl-string->list str) 0))) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Hey_Its_Sanka Posté(e) le 22 octobre 2023 Auteur Posté(e) le 22 octobre 2023 Salut Gile, tu peux m'éclairer un peu sur les arguments inclus dans tes lisp? J'ai du mal 😅 Mettons que je te donne : (setq txty "Seuil égal à : 76.84m...") Comment tu écris le lisp avec cette donnée au début ? (sachant qu'avant et après l'altitude, il pourrait y avoir absolument nimporte quel caractère) Merci
(gile) Posté(e) le 22 octobre 2023 Posté(e) le 22 octobre 2023 La première solution avec les expressions régulières illustre assez bien la blague : "Certaines personnes, lorsqu'elles sont confrontées à un problème, se disent "Je sais, je vais utiliser des expressions régulières". Maintenant, elles ont deux problèmes." Je vais donc plutôt essayer d'expliquer comment fonctionne la seconde (que j'ai modifiée). Tout d'abord, parce que LISP est basé sur les listes, on traiter le problème en utilisant une liste de caractères (nombres entiers) plutôt qu'une chaîne de caractères. La fonction vl-string->list convertit une chaine de caractère en liste d'entiers (les codes ASCII des caractères). La fonction vl-list->string permettra de faire la conversion inverse du résultat. Pour traiter la liste, on utilise une fonction récursive qui prend en argument la liste de caractères et un drapeau qui indique si aucun chiffre n'a encore été trouvé (0), un ou plusieurs chiffres ont été trouvés (1), un point (séparateur décimal) a été trouvé après des chiffres (1 | 2 = 3). Qui dit fonction récursive, dit condition d'arrêt. Dans ce cas deux conditions peuvent être rencontrées : la liste est vide ou un caractère non numérique est trouvé alors que le drapeau est supérieur à 0. Pour ces deux conditions la fonction revoie nil. La fonction parcourt la liste élément par élément en constituant la liste qui sera renvoyée avec uniquement des chiffres et, éventuellement un point. Exemple avec une chaîne simple : "ht=12.5m". ;; Premier appel (premier caractère = 'h') (loop (104 116 61 49 50 46 53 109) 0) ;; Second appel (second caractère = 't') (loop (116 61 49 50 46 53 109) 0) ;; Troisième appel (troisième caractère = '=') (loop (61 49 50 46 53 109) 0) ;; Quatrième appel (quatrième caractère = '1') (loop (49 50 46 53 109) 0) ;; Cinquième appel (cinquième caractère = '2') (cons 49 (loop (50 46 53 109) 1)) ;; Sixième appel (sixième caractère = '.') (cons 49 (cons 50 (loop (46 53 109) 1))) ;; Septième appel (septième caractère = '5') (cons 49 (cons 50 (cons 46 (loop (53 109) 3)))) ;; Huitième appel (huitième caractère = 'm') (cons 49 (cons 50 (cons 46 (cons 53 (loop (109) 3))))) ;; Dépilement (cons 49 (cons 50 (cons 46 (cons 53 nil)))) (cons 49 (cons 50 (cons 46 '(53)))) (cons 49 (cons 50 '(46 53))) (cons 49 '(50 46 53)) (49 50 46 53) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 22 octobre 2023 Posté(e) le 22 octobre 2023 Comme je sais que certains ont du mal avec la récursivité, voilà l'équivalent avec une boucle while (defun miracle (str / lst res break dot) (setq lst (vl-string->list str)) (while (and lst (not break)) (cond ((< 47 (car lst) 58) (setq res (cons (car lst) res) lst (cdr lst) ) ) ((= 46 (car lst)) (if dot (setq break T) (if res (setq res (cons 46 res) lst (cdr lst) dot T ) (setq lst (cdr lst)) ) ) ) (T (if res (setq break T) (setq lst (cdr lst)) ) ) ) ) (distof (vl-list->string (reverse res))) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Hey_Its_Sanka Posté(e) le 1 novembre 2023 Auteur Posté(e) le 1 novembre 2023 Merci Gile pour ta réponse!
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