Get the position of the last numeric character in a string

Get the position of the last numeric character in a string

Anonymous
Not applicable
1,788 Views
7 Replies
Message 1 of 8

Get the position of the last numeric character in a string

Anonymous
Not applicable

I'm looking for a function to get the position of the last numeric character in an alphanumeric string.  I found one from Lee_Mac below but it's for the first number in a string and I'm what I'm after is for the last numeric character.

 

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/find-position-of-1st-number-in-a-str... 

(defun numpos ( str )
    (if (wcmatch str "*#*")
        (- (strlen str) (length (vl-member-if '(lambda ( x ) (< 47 x 58)) (vl-string->list str))))
    )
)

 

"This is a sample string with numbers like 0, 1, 2.5, 3a, 4.04 and 5.06 and some other symbols such as  *, #, (,) etc."

 

So, based from the above example, I'm looking for the position of the last numeric character which is 6 and the string is not constant.   Thanks.

 

0 Likes
Accepted solutions (2)
1,789 Views
7 Replies
Replies (7)
Message 2 of 8

marko_ribar
Advisor
Advisor
Accepted solution
(defun numpos ( str )
    (if (wcmatch str "*#*")
        (- (strlen str) (length (vl-member-if '(lambda ( x ) (< 47 x 58)) (reverse (vl-string->list str)))))
    )
)

HTH., M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 3 of 8

marko_ribar
Advisor
Advisor
Accepted solution

@marko_ribar wrote:
(defun numpos ( str )
    (if (wcmatch str "*#*")
        (- (strlen str) (length (vl-member-if '(lambda ( x ) (< 47 x 58)) (reverse (vl-string->list str)))))
    )
)

HTH., M.R.


Actually I didn't think deeply... It should be just :

 

(defun numpos ( str )
    (if (wcmatch str "*#*")
        (length (vl-member-if '(lambda ( x ) (< 47 x 58)) (reverse (vl-string->list str))))
    )
)

 

Regards, M.R.

 

 

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 4 of 8

Anonymous
Not applicable

That's brilliant. 👏 The first solution was good enough for me.  😀  It's counting the position from the end  rather than the start of the string but I can do some small tweaks to suit what I needed.  Thanks very much for your help and stay safe.

0 Likes
Message 5 of 8

peter.molander
Explorer
Explorer

Hi!

I tried to use this code, but there is something I dont understand about how it works.

 

Used it in an second IF-statement and it works as intended but after It leaves the statement I still get the "nil" as a return in the end. I dont want this.

(defun c:numpos () 
  (setq mystring "TEST.abc.123")
    (if (wcmatch mystring "*#*")
      (if (< 2 (- (strlen mystring) (length (vl-member-if-not '(lambda ( x ) (< 47 x 58)) (reverse (vl-string->list mystring))))))
	(prompt mystring) 
	(prompt "1st-else") 
	    );_if
      (prompt "2nd-else")
    );_if
)

 Notice: I also changed the vl-member to a not since I want to know the amount of numberd characters the string has in the end!

 

Thanks!

0 Likes
Message 6 of 8

ronjonp
Advisor
Advisor

@peter.molander Not exactly sure what you're needing out of this but see if this helps:


(setq mystring "TEST.abc.123")
(setq n 0)
(vl-remove 'nil
  (mapcar '(lambda (x)
	     (setq n (1+ n))
	     (if (< 47 x 58)
	       (cons n (chr x))
	     )
	   )
	  (vl-string->list mystring)
  )
)
;; Returns '((position chr)(position chr)(position chr))
;; ((10 . "1") (11 . "2") (12 . "3")) 
0 Likes
Message 7 of 8

Kent1Cooper
Consultant
Consultant

@peter.molander wrote:

.... I still get the "nil" as a return in the end. I dont want this. ....


Add this just before the closing right parenthesis at the end:

....

     );_if
     (prompt "2nd-else")
  );_if
  (prin1)
)

 

[Or (print) or (princ) -- any of them with no arguments.]  See Help for the (prin1) function, where it describes this as "exiting quietly."

Kent Cooper, AIA
Message 8 of 8

peter.molander
Explorer
Explorer
Perfect, did not know about the (prin1) function, will come in handy. Thanks! 🙂
0 Likes