searchemacsmatch-data

match-data not cleared on failed re-search-forward


I need to make multiples re-search'es in a buffer.

But when the last re-search fails, the match-data still contains the former result.

foo-bar-baz

(progn
  (goto-char (point-min))
  (re-search-forward "^foo-\\(.*\\)-baz" nil t)
  (message "step 1: %S '%s'" (match-data) (match-string-no-properties 1))
  ;; => step 1: (#<marker at 1 in *scratch*> #<marker at 12 in *scratch*> #<marker at 5 in *scratch*> #<marker at 8 in *scratch*>) ’bar’

  (goto-char (point-min))
  (re-search-forward "^baz-\\(.*\\)-foo" nil t)
  (message "step 2: %S '%s'" (match-data) (match-string-no-properties 1))
  ;; => step 2: (#<marker at 1 in *scratch*> #<marker at 12 in *scratch*> #<marker at 5 in *scratch*> #<marker at 8 in *scratch*>) ’bar’
  ;; expected no match-data
  )

I don't get how to use set-match-data and need to know when the last re-search don't matches.

Any advise on a lispy way to do such re-searches ?

Setting NOERROR to t seems to the root cause but clearer than excpecting errors everywhere in my re-searches.


Solution

  • According to @Drew suggestion save-match-data give an all new match-data just as I wanted:

    foo-bar-baz
    
    (progn
      (save-match-data
        (goto-char (point-min))
        (re-search-forward "^foo-\\(.*\\)-baz" nil t)
        (message "step 1: %S" (match-string-no-properties 1))) 
    ;; => step 1 : "bar"
    
      (save-match-data
        (goto-char (point-min))
        (re-search-forward "^baz-\\(.*\\)-foo" nil t)
        (message "step 2: %S" (match-string-no-properties 1))) 
    ;; => step 2: no nil
      )