Sumar números en la región

8

¿Cómo puedo sumar un conjunto de números intercalados con texto en la región (no una región rectangular)? Por ejemplo, si la región contiene este texto:

Widgets 234
Sprockets 44
Nubbins 12
Fork handles 4
4 Candles

Estoy buscando un comando que informe 298 de alguna manera (298 = 234 + 44 + 12 + 4 + 4). Supongo que haciendo eco en el área del mensaje o insertándolo en el búfer.

Lo ideal sería hacer frente tanto a los enteros como a los números de coma flotante.

Croad Langshan
fuente
1
Claramente faltan ejemplos "Ronnies 2" :)
phils

Respuestas:

6

Aquí hay uno:

(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)))

Debido a que usa string-to-number, tratará el token "1hello" como el número "1", pero no tratará "hello2" como un número. También funciona con decimales (p. Ej., 2.4).

zck
fuente
5

Específicamente para su caso, suponiendo que este sea el texto completo del búfer:

  1. M-xreplace-regexpRET[^0-9]+RET+RET
  2. C-x h - seleccionar todo.
  3. C-x * e (asegúrese de que no haya ningún signo más) .
wvxvw
fuente
Me reemplazan con un + al final de la línea que no le gustaba al modo calc: funcionó cuando eliminé eso. Respuesta interesante aunque un poco incómoda para este caso de uso simple.
Croad Langshan
3
Otra calcsolución: marca la región, C-x * gpara agarrar, V u( calc-unpack), luego toca +hasta que hayas sumado todos los números.
niñera
2

No conozco un comando incorporado que haga esto, pero podrías hacer el tuyo propio:

(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)))
Kyle Meyer
fuente
La respuesta de @ zck es mejor (siempre y cuando estés de acuerdo con que el número sea parte de la palabra). La expresión regular en esta respuesta necesitaría extenderse para admitir números negativos.
Kyle Meyer