I have written the following code

(defun krmet-replace()
    ;; Narrow to the region
     (progn (search-forward "C %% MODULE %%")
     (progn (search-forward "C %% END MODULE %%")

    ;; Find Replace
    (goto-char (point-min))
    (while (search-forward "KRMET" nil t)
      (replace-match "KR23" nil t))           ;; remove the hard coded replacement, use user input
    (goto-char (point-min))
    (while (search-forward "KR-MET" nil t)
      (replace-match "KR-23" nil t)))))       ;;;; remove the hard coded replacement, use user input

(global-set-key (kbd "C-c #") 'krmet-replace)

There are two things that I don not know how to do:

  1. How to interactively pass a number, in this case it is "23". I want to replace KRMET with KR23. I modified the code like shown below
(defun krmet-replace (r)
  (interactive "nRx # : ")

and used the r in replace match line like so

(replace-match (concat "KR" string(r)) nil t))

I get this error: replace-match: Symbol’s value as variable is void: string

Answer Edit:
I fixed the first problem like so using number-to-string function

    (goto-char (point-min))
    (while (search-forward "KRMET" nil t)
      (replace-match (concat "KR" (number-to-string r)) nil t))
    (goto-char (point-min))
    (while (search-forward "KR-MET" nil t)
      (replace-match (concat "KR-" (number-to-string r)) nil t)))))
  1. How to replace string using regex? Like KRMET or KR-MET with KRnn or KR-nn where nn is the user provided number when running the function
  • I think you're looking for (format "KR-%d" r) to convert your number into a string? Use %02d if single digit numbers should have a zero prefixed. – phils Sep 16 at 4:09
  • 1
    n.b. Your question is pretty clear in general, but please never write something like "It is throwing different errors" without actually including the text of the error messages. The error text will help others to see what the problem is. – phils Sep 16 at 4:14
  • @phils I have edited the question with the error description – Prasanna Sep 16 at 5:12
  • Regarding the edit, note that string(r) isn't passing r to a function string; it's two separate expressions: string -- evaluating the variable string, and (r) -- calling the function r. Hence the error "Symbol’s value as variable is void: string" because it turned out that string wasn't a variable. As you established yourself, (number-to-string r) was how that should have looked. I would still suggest using format, but either approach is fine. – phils Sep 16 at 5:55

Here's an example of using format as well as performing both sets of replacements in a single pass by matching a regular expression:

(goto-char (point-min))
(while (re-search-forward "\\(KR-?\\)MET" nil t)
  (replace-match (format "%s%d" (match-string 1) r)
                 nil t))

Or adapting your concat approach:

(concat (match-string 1) (number-to-string r))


Originally I suggested the regexp "KR\\(-\\)?MET" which complicated things slightly for the format case, as match-string returns nil if the sub-group didn't match anything, and (format "%s" nil) returns "nil" rather than "", so I needed to use (format "KR%s%d (or (match-string 1) "") r) to avoid that. Conversely (concat "KR" (match-string 1) (number-to-string r)) was fine, as nil arguments to concat are ignored -- because in elisp nil is an empty list, so it's a list argument which doesn't add anything to the concatenation.

In any case, including the "KR" inside the sub-group ensures the group can't be nil, which simplifies things.

Using "KR\\(-?\\)MET" instead of "KR\\(-\\)?MET" would also have avoided the nil issue, as that would have caused the group to match the empty string when required.

| improve this answer | |

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.