用lookahead / behind替换-regexp-in-string

时间:2012-10-09 22:58:18

标签: emacs elisp

我想在字符串中用\w \w替换所有出现的\w\\\w,其中\w部分在替换之前和之后保持不变,例如

[.A foobar] [.B baz]

应该导致

[.A\\foobar] [.B\\baz]

它也适用于

[.A' foobar] [.B -baz]

=>

[.A'\\foobar] [.B\\-baz]

来自jlf @ #emacs

(while (string-match "\(.*\w\) \(\w\)" str)
  (setq str (concat (match-string 1 str) "\\" (match-string 2 str))))

2 个答案:

答案 0 :(得分:2)

(replace-regexp-in-string“\\ _< \\ w + \\ _>”(lambda(x)(concat“\\\\ s”(substring x 1)))mystring)

答案 1 :(得分:1)

这可能有点多才多艺:

(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"

最终可能会更快:)