Summenzahlen in der Region

8

Wie kann ich eine Reihe von Zahlen summieren, die mit Text in der Region durchsetzt sind (keine rechteckige Region)? Wenn die Region beispielsweise diesen Text enthält:

Widgets 234
Sprockets 44
Nubbins 12
Fork handles 4
4 Candles

Ich suche nach einem Befehl, der 298 irgendwie meldet (298 = 234 + 44 + 12 + 4 + 4) - ich denke, entweder indem ich ihn in den Nachrichtenbereich wiedergebe oder ihn in den Puffer einfüge.

Idealerweise würde es sowohl Ganzzahlen als auch Gleitkommazahlen verarbeiten.

Croad Langshan
quelle
1
Beispiele fehlen eindeutig "Ronnies 2" :)
Phils

Antworten:

6

Hier ist eine:

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

Da es verwendet wird string-to-number, wird das Token "1hello" als Nummer "1" behandelt, "hello2" jedoch nicht als Nummer. Es funktioniert auch mit Dezimalstellen (z. B. 2.4).

zck
quelle
5

Speziell für Ihren Fall, vorausgesetzt, dies ist der gesamte Text des Puffers:

  1. M-xreplace-regexpRET[^0-9]+RET+RET
  2. C-x h - Wählen Sie Alle.
  3. C-x * e (Stellen Sie sicher, dass kein nachfolgendes Pluszeichen vorhanden ist) .
wvxvw
quelle
Das ersetzt mich durch ein abschließendes + am Ende der Zeile, was dem Calc-Modus nicht gefallen hat: Es hat funktioniert, als ich das entfernt habe. Interessante Antwort, wenn auch etwas unpraktisch für diesen einfachen Anwendungsfall.
Croad Langshan
3
Eine andere calcLösung: Region markieren, C-x * ggreifen, V u( calc-unpack) und dann tippen, +bis Sie alle Zahlen summiert haben.
Kindermädchen
2

Ich kenne keinen eingebauten Befehl, der dies tut, aber Sie könnten Ihren eigenen erstellen:

(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
quelle
Die Antwort von @ zck ist besser (solange Sie damit einverstanden sind, dass die Zahl Teil des Wortes ist). Der reguläre Ausdruck in dieser Antwort müsste erweitert werden, um negative Zahlen zu unterstützen.
Kyle Meyer