# Finding Numbers in Brackets and Summing Them

QUESTION:

How can I make an emacs command `M-x sum-the-brackets` that scans highlighted text for all occurrences of `[ <number> u ]` and `[ <number>u ]`, and sums them?

EXAMPLE:

Selecting the text

``````Here is some text. [0.1u]
Here is some more text [0.2 u]
And here is some noise: 0.2
``````

and running `M-x sum-the-brackets` should yield `0.3` in the mini-buffer.

You want to search for all instances of the regular expression `\[ *\([-0-9.]+\) *u *\]`:

``````(re-search-forward "\\[ *\\([-0-9.]+\\) *u *\\]" nil t)
``````

and sum the matches:

``````(setq sum (+ sum (string-to-number (match-string 1))))
``````

Since you want this to apply to the region only, you'll need to `narrow-to-region` and then restore the restriction using `save-restriction`.

Putting this all together, we get:

``````(defun my-sum (begin end)
(interactive "r")
(save-restriction
(save-excursion
(narrow-to-region begin end)
(goto-char (point-min))
(let ((sum 0))
(while (re-search-forward "\\[ *\\([-0-9.]+\\) *u *\\]" nil t)
(setq sum (+ sum (string-to-number (match-string 1)))))
(message "%s" sum)
sum))))
``````

Using standard commands:

``````M-: (setq n 0) RET
C-M-% \[\([0-9.]+\) *u\] RET \,(prog1 \& (setq n (+ n \#1))) RET !
M-: n RET
``````

Note: to get more information have a look at help for `query-replace-regexp`, `prog1` and `eval-expression`

– jue
Jul 11, 2017 at 9:27

Here is the function you wished for.
I put some extra variables inside this function, so it is easier for you to enhance it.

``````(defun sum-the-brackets (begin end)
"sums up values in brackets with style '[ FLOAT u ]'
For non interactive use BEGIN must be smaller then END.
If FLOAT is omitted bracket counts with value one
If FLOAT is '.' it counts as value 0
Whitespace inside the brackets is ignored"
(interactive "r")
(save-excursion
(let ((n 0)       ; desired value
(c 0)       ; counter
(tmp nil)   ; string in bracket
(tmpf 0))   ; value of string in bracket
(goto-char begin)
(while (search-forward-regexp "\\[ *\\([0-9]*\\.?[0-9]*\\) *\\(u *\\)\\]" end t)
(setq c (1+ c))
(setq tmp (match-string 1))
(setq tmpf (if (string= "" tmp) 1
(string-to-number tmp)))
(setq n (+ n tmpf)))
(message "Sum-Value: %2.3f ; brackets counted: %d" n c))))
``````

This function sums up following 6 brackets to value 3.6:

``````Here is some text. [0.1u]
Here is some more text [ 0.2 u]
count me with value zero point 3 [.3 u]
count me with value two [2 u]
count me with value one [u]
count me with zero [ . u ]
And here is some noise: 0.2
``````

Note: politza answer is way more cool. :)

Note2: comments/edits on improvement of the code are very welcome, I did code this for practice and it took me a while. :)

Edit: the user "jch" changed the question. I will not update this answer because "jch" gave an answer which fits his edits and maybe someone else finds my answer useful.

• 1. Is narrowing really necessary ? 2. Second argument of `search-forward-regexp` you gave is also the default. 3. It's always nice beeing able to use a command as function as well, i.e. use `(begin end)` arguments and setup interactive usage in the `(interactive)` spec appropriately. Jul 11, 2017 at 21:59
• @politza many thanks for your constructive comment! I changed the code accordingly. Also I spotted, that the questioner wanted to evaluate `[u]`.
– jue
Jul 11, 2017 at 23:55
• The apparent `[u]` in the orignal answer was a typo, due to some misquoted markup. I merely fixed the markup, which caused the spurious `[u]` to disapper. As to your answer — please keep it around, it's good to have multiple solutions written in different styles.
– jch
Jul 13, 2017 at 18:44
• You also wrote a good and correct answer, so there is no need to have a correct answer a second time. Besides, my original code, before my edit looks nearly the same like yours and I don't want to revert my code. Everything is fine! :)
– jue
Jul 13, 2017 at 18:50