If I'm not mistaken, the solutions provided so far (using Perl and Vim) do not work correctly when any of the replacements is among the latter words to be replaced. In particular, none of the solutions works for the first example: "i" would be replaced with "in", which would then be incorrectly replaced with "ni" and then back to "i" by the subsequent rules, while it should stay as "in".
The substitutions cannot be assumed independent and applied in succession; they should be applied in parallel.
In Emacs, you can do this:
M-x parallel-replace,
and at the prompt, enter
i in in ni ni i.
The replacements will happen between the cursor and the end of buffer, or in a region if one is selected.
(Of course, provided you have this definition in your ~/.emacs.d/init.el
:-)
(require 'cl)
(defun parallel-replace (plist &optional start end)
(interactive
`(,(loop with input = (read-from-minibuffer "Replace: ")
with limit = (length input)
for (item . index) = (read-from-string input 0)
then (read-from-string input index)
collect (prin1-to-string item t) until (<= limit index))
,@(if (use-region-p) `(,(region-beginning) ,(region-end)))))
(let* ((alist (loop for (key val . tail) on plist by #'cddr
collect (cons key val)))
(matcher (regexp-opt (mapcar #'car alist) 'words)))
(save-excursion
(goto-char (or start (point)))
(while (re-search-forward matcher (or end (point-max)) t)
(replace-match (cdr (assoc-string (match-string 0) alist)))))))
Edit: Revised definition accepts unquoted strings.