Take the 2-minute tour ×

I'm looking for the fastest routine (not interactively) to get the number of matches of a regexp in a string.

Something like

(count-occurrences "a" "alabama")
=> 4
share|improve this question

3 Answers 3

up vote 2 down vote accepted

Here is a more functional answer using recursion and an accumulator. As an added benefit, it does not use cl:

(defun count-occurences (regex string)
  (recursive-count regex string 0))

(defun recursive-count (regex string start)
  (if (string-match regex string start)
      (+ 1 (recursive-count regex string (match-end 0)))
share|improve this answer
This might look and feel more elegant, but without tail-call optimization, the recursive solution is bound by the stack size. It will also be slower due to stack maintenance. –  event_jr Aug 7 '12 at 23:10
Very true. I was thinking the way it was done in Haskell. With that method I can count up to 197 occurences. –  Nicolas Dudebout Aug 7 '12 at 23:22
@event_jr do you know of any way to bypass that problem? –  Nicolas Dudebout Aug 8 '12 at 14:16
Not really. Emacs-lisp just does not lend itself to recursive solutions well. I tend to think of Emacs-lisp as procedural with first-class functions, not really functional. –  event_jr Aug 8 '12 at 14:36

count-matches does it interactively. Maybe a good place to start looking.

share|improve this answer
Yes, it uses search-forward, witch is also interactive-oriented... I know what I'm going to do ; I'm going to google for "How can I benchmark single defuns in elisp". –  xaccrocheur Aug 7 '12 at 14:50

how-many (aliased count-matches) does this, but works on buffers.

Here is one that works on strings:

(defun how-many-str (regexp str)
  (loop with start = 0
        for count from 0
        while (string-match regexp str start)
        do (setq start (match-end 0))
        finally return count))
share|improve this answer
I wanted to avoid using cl functions, but hey, it works. –  xaccrocheur Aug 7 '12 at 14:48
loop is a macro, compiles away completely, no problems. –  event_jr Aug 7 '12 at 14:54

Your Answer


