Here's a chunk of code:

(defvar test-string "bla bla bla bla bla bla")

(string-match "[[:digit:]]+\\.[[:digit:]]+\\.[[:digit:]]+\\.[[:digit:]]+" test-string)
(message (match-string 0 test-string))

When I select the entire block it's evaluated correctly (using eval-region):

When I evaluate sequentially (using eval-last-sexp) I get the following:

bla bla bla 10.1

I've looked at the docs of the respective functions but couldn't find any help.

My Emacs version is GNU Emacs 24.5.1 (x86_64-apple-darwin14.3.0, Carbon Version 157 AppKit 1347.57).

  • 1
    I don't have an eval-current-form-sp, where does it come from?
    – db48x
    Nov 23 '15 at 17:22
  • Ah! Apptly it comes with spacemacs. I'll post it's definition Nov 23 '15 at 17:24
  • @db48x I've changed it to use the stock emacs function. Still weird behavior. Nov 23 '15 at 17:28

When you evaluate sequentially, there is a boat load of Elisp code executed between those to statements, and of course, this Elisp code will almost inevitably end up using regular expressions, so the match-data of your first expression will be long gone by the time you run the second.

What kind of Elisp code might be run between the two? Let's see:

  • the code that you trigger when you try and move the cursor to the second expression
  • the code of eval-last-sexp
  • the code to recompute the mode-line, and frame title
  • maybe some background timers
  • possibly some font-lock refresh
  • maybe some procees filter
  • ...

match-data is very much transient, if not fleeting, so you have to use it right after you've performed the regexp match. If you're not sure if you do it quickly enough, then you can generally assume that it's not soon enough (i.e. assume that all functions can destroy the match-data, except for a few core functions like car, cdr, ...).

  • Coming back to this answer again, I realized it's a pretty bad software engineering in my opinion... Maybe it'd be worth communicating it to the Emacs maintainers. Jan 4 '16 at 21:33
  • No doubt it's a bad design. But it's kinda late to fix it.
    – Stefan
    Jan 5 '16 at 3:38

`C-h f match-string:

Return string of text matched by last search.

Likely that call to string-match was not the last search (maybe check the definition of command eval-last-sexp etc.).

Judging by the position values shown in the error message, the last match was against buffer text. Try using save-match-data.


string-match sets global state which match-string uses. If you did another match (which many commands might do internally), then this global data will be from a different match, and will have different saved start and end points. The error you mention is because the saved start and end points were outside the string you passed to match-string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.