I have a dictionary key-values dict.tsv file like this:

key1 value1
key2 value2
key3 value3

And my text.txt file has this:

blah blah asdf saf key2 asd blah key1
blah key1
blah key2
blah key3

How do I get this:

blah blah asdf saf key2/value2 asd blah key1/vaue1
blah key1/value1
blah key2/value2
blah key3/value3

I imagine a function working like this:

lookup-and-replace-with-an-association-list works like this

  1. M-x lookup-and-replace-with-an-association-list RET
  2. Input path to dict.tsv and use the whole file content for lookup and replace. Or if no file provided, select the content from current highlighted region.
  3. (internally) Parse the content to a association list dict.list
  4. Input key regex pattern. If no pattern given, take all the keys in the dict.list.
  5. Input replace pattern with value. In my case: keyX/valueX.
  6. Optional, maybe a interactive confirmation yes, no or do-all would be nice.
  • 1
    1. I think you've swapped key1 and key2 in the first line. 2. You need to tell if it is possible to do iteratively, or not (suppose that by replacing the first key you create additional key2 - should that key2 be processed when replacing the matches for the next key, or not?)
    – wvxvw
    Aug 10, 2015 at 12:49
  • @wvxvw: My bad about swapping the key order, I updated it. You are asking what if, for example, value1 happens to be key2. For simplicity, keys are unique and never equal to any of the values. Aug 10, 2015 at 12:55

1 Answer 1


Here's something that seems to do what you want:

(defun my/multy-key-replace (keys target)
  (interactive "fFile to read the keys from: 
fFile to replace: ")
  (let ((repbuffer (get-buffer-create "*Replacements*")))
      (insert-file-contents keys)
      (let ((replacements (make-hash-table :test 'equal)))
        (while (re-search-forward "^\\([^ ]+\\) \\([^ ]+\\)$" nil t)
          (setf (gethash (match-string 1) replacements)
                (match-string 2)))
        (with-current-buffer repbuffer
          (insert-file-contents target)
           (lambda (key value)
             (goto-char (point-min))
             (replace-string key (format "%s/%s" key value)))
    (pop-to-buffer repbuffer)))
  • seems to works well.
    – Name
    Aug 11, 2015 at 22:51
  • This lacks some flexibility I described, but works good enough. If I use this more frequently I will post back my customization. @wvxvw: Really appreciate your help. Aug 12, 2015 at 22:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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