Soma números na região

8

Como posso somar um conjunto de números intercalados com texto na região (não uma região retangular). Por exemplo, se a região contiver este texto:

Widgets 234
Sprockets 44
Nubbins 12
Fork handles 4
4 Candles

Estou procurando um comando que reportará 298 de alguma forma (298 = 234 + 44 + 12 + 4 + 4) - acho que ecoando isso na área de mensagem ou inserindo-o no buffer.

Idealmente, ele lidaria com números inteiros e números de ponto flutuante.

Croad Langshan
fonte
11
Faltam exemplos claramente de "Ronnies 2" :) #
phils 27/04

Respostas:

6

Aqui está um:

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

Por usar string-to-number, ele tratará o token "1hello" como o número "1", mas não tratará "hello2" como um número. Também funciona com decimais (por exemplo, 2.4).

zck
fonte
5

Especificamente para o seu caso, supondo que este seja o texto inteiro do buffer:

  1. M-xreplace-regexpRET[^0-9]+RET+RET
  2. C-x h - selecionar tudo.
  3. C-x * e (verifique se não há sinal de mais à direita) .
wvxvw
fonte
O substitui-me por um + no final da linha que o modo calc não gostou: funcionou quando o removi. Resposta interessante, embora um pouco inconveniente para este caso de uso simples.
Croad Langshan
3
Outra calcsolução: marque a região, C-x * gpara pegar, V u( calc-unpack) e depois toque em +até somar todos os números.
nanny
2

Não conheço um comando interno que faça isso, mas você pode criar o seu:

(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
fonte
A resposta de @ zck é mais agradável (desde que você esteja bem com o número fazendo parte da palavra). O regexp nesta resposta precisaria ser estendido para suportar números negativos.
Kyle Meyer