这可能更通用一点:
(defun replace-between-words (input replacement &optional preserve)
"Replaces white space between two words with REPLACEMENT
if REPLACEMENT is a character, and PRESERVE is not NIL, then
that character is duplicated as many times as there are white spaces
between words. If PRESERVE is NIL, then only one character is
inserted.
If REPLACEMENT is a string and PRESERVE is not NIL, then it is rolled
into the available white space, otherwise the entire replacement string
is insterted."
(with-output-to-string
(let ((match "*") (replaced t)
(white-count 0)
seen-start seen-end current whites)
(dotimes (i (length input))
(setf current (aref input i)
(aref match 0) current)
(cond
((string-match "\\w" match)
(if seen-end
(progn
(if (stringp replacement)
(if preserve
(dotimes (j white-count)
(write-char
(aref replacement
(mod j (length replacement )))))
(princ replacement))
(if preserve
(dotimes (j white-count)
(write-char replacement))
(write-char replacement)))
(setq seen-end nil))
(setq seen-start t))
(setq whites nil white-count 0)
(write-char current))
((member current '(?\ ?\t ?\n ?\r))
(if seen-start
(if seen-end
(progn
(setq whites (cons current whites))
(incf white-count))
(setq seen-end t white-count 1 whites (list ?\ )))
(write-char current)))
(t (when (> white-count 0)
(princ (coerce whites 'string))
(setq white-count 0 whites nil))
(write-char current)
(setq seen-end nil seen-start nil)))))))
(replace-between-words "[.A foobar] [.B baz]" ?\/)
"[.A/foobar] [.B/baz]"
(replace-between-words "[.A foobar] [.B baz]" "-=*=-" t)
"[.A-foobar] [.B-=*baz]"
(replace-between-words "[.A foobar] [.B baz]" "-=*=-")
"[.A-=*=-foobar] [.B-=*=-baz]"
(replace-between-words "[.A foobar] [.B baz]" ?\/ t)
"[.A/foobar] [.B///baz]"
(replace-between-words "[.CP [.TP [.NP" ?\/ t)
"[.CP [.TP [.NP"
并且最终可能会更快:)