7

How can I sum a set of numbers interspersed with text in the region (not a rectangular region). For example, if the region contains this text:

Widgets 234
Sprockets 44
Nubbins 12
Fork handles 4
4 Candles

I'm looking for a command that will report 298 somehow (298 = 234 + 44 + 12 + 4 + 4) -- I guess either by echoing that to the message area or inserting it in the buffer.

Ideally it would cope with both integers and floating point numbers.

  • 1
    Examples are clearly missing "Ronnies 2" :) – phils Apr 27 '15 at 10:45
6

Here's one:

(require 'cl-lib)
(defun sum-numbers-in-region (start end)
  (interactive "r")
  (message "%s"
           (cl-reduce #'+
                      (split-string (buffer-substring start
                                                      end))
                      :key #'string-to-number)))

Because it uses string-to-number, it will treat the the token "1hello" as the number "1", but won't treat "hello2" as a number. It also works with decimals (e.g., 2.4).

4

Specifically for your case, assuming this is the entire text of the buffer:

  1. M-xreplace-regexpRET[^0-9]+RET+RET
  2. C-x h - select all.
  3. C-x * e (make sure there is no trailing plus sign).
  • The replace me with a trailing + at the end of the line which calc-mode didn't like: it worked when I removed that. Interesting answer though a bit inconvenient for this simple use case. – Croad Langshan Apr 26 '15 at 21:50
  • 3
    Another calc solution: mark region, C-x * g to grab, V u (calc-unpack), then tap + until you've summed all the numbers. – nanny Apr 27 '15 at 13:12
2

I don't know of a built-in command that does this, but you could make your own:

(defun sum-region-nums (beg end)
  (interactive "r")
  (save-excursion
    (goto-char beg)
    (let (nums total)
      (while (re-search-forward "\\b[0-9]+\\(\\.[0-9]+\\)*\\b" end t)
        (push (string-to-number (match-string-no-properties 0))
              nums))
      (setq total (apply #'+ nums))
      (message "%s" total)
      total)))
  • @zck's answer is nicer (as long as you're ok with the number being part of the word). The regexp in this answer would need to be extended to support negative numbers. – Kyle Meyer Apr 26 '15 at 20:04

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.