2

The following function fails to return "16":

(string-to-number "bm16")

It seems to get tripped up if the first characters of a string aren't numbers. Is there a way to construct an elisp function which takes a string of text and returns the number it contains (it doesn't have to handle decimals)?

3
  • There is no function named first-number-from-string in my emacs: how is it defined? where did you get it from? – NickD Mar 17 at 5:00
  • NickD: My mistake. I meant string-to-number. – George Mar 17 at 5:22
  • What should happen for the string "abcdef" which contains no digits? And do you want the result to be a number or its string representation? – NickD Mar 17 at 5:27
2

A possible implementation: find the first digit, get the substring of the original string that starts at that first digit and then call string-to-number on the result:

(defun first-number-of-string (s)
  (string-to-number (substring s (string-match-p "[0-9]" s))))

(first-number-of-string "bm16" -> 16
(first-number-of-string "abc123def456" -> 123
(first-number-of-string "abc123") -> 123
(first-number-of-string "123def") -> 123
(first-number-of-string "123") -> 123
(first-number-of-string "abcdef") -> 0

That's assuming that the answers to the questions in my comment are that you indeed want a number, not its string representation, and in the case where there is no number in the string, having the function return 0 is acceptable.

1

An alternative using cl functions:

(defun first-number-in-string(s)
   (string-to-number
     (seq-take-while
     #'cl-digit-char-p 
     (seq-drop-while
      (lambda(x)(not (cl-digit-char-p x)))
      s))))

    (mapcar #'first-number-in-string 
'( "bm16" "abc123def456" "abc123" "123def" "123" "abcdef")) 
=>     (16 123 123 123 123 0)

The same algorithm splitted for clarity::

(defun collect-first (pred coll)
  (seq-take-while pred
                  (seq-drop-while (lambda (x) (not(funcall pred x)))
                                  coll)))


(defun first-number-in-string(s)
   (string-to-number
     (collect-first #'cl-digit-char-p  s)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.