why are multiple re-search-foward / replace-match calls not replacing allmatches?
I want to do a set of search and replace operations in emacs, so I wrote this function:
defun untwist ()
(interactive)
(while (re-search-forward "yield " nil t) (replace-match ""))
(while (re-search-forward "@defer.inlineCallbacks" nil t) (replace-match ""))
(while (re-search-forward "defer.returnValue" nil t) (replace-match "return "))
(while (re-search-forward "@inlineCallbacks" nil t) (replace-match ""))
(while (re-search-forward "returnValue" nil t) (replace-match "return "))
(while (re-search-forward "^from twisted\.+\n" nil t) (replace-match ""))
(while (re-search-forward "(session," nil t) (replace-match "("))
(while (re-search-forward "session\.log(\(.*\))" nil t) (replace-match "print \1"))
)
However, only some of the substitutions get done. I ran it on:
@defer.inlineCallbacks
yield x
and got:
@defer.inlineCallbacks
x
What am I doing wron开发者_如何学JAVAg?
Your problem is that, after the first "while" statement successfully replaces the "yield" statement, the "point" is positioned to the end of the buffer. Therefore, all subsequent RE searches don't find anything to replace because their searches start at the end of the buffer! You can easily fix this by re-positioning to the beginning of the buffer after each search:
(defun untwist ()
(interactive)
(while (re-search-forward "yield " nil t) (replace-match ""))
(beginning-of-buffer)
(while (re-search-forward "@defer.inlineCallbacks" nil t) (replace-match ""))
(beginning-of-buffer)
(while (re-search-forward "defer.returnValue" nil t) (replace-match "return "))
(beginning-of-buffer)
(while (re-search-forward "@inlineCallbacks" nil t) (replace-match ""))
(beginning-of-buffer)
(while (re-search-forward "returnValue" nil t) (replace-match "return "))
(beginning-of-buffer)
(while (re-search-forward "^from twisted\.+\n" nil t) (replace-match ""))
(beginning-of-buffer)
(while (re-search-forward "(session," nil t) (replace-match "("))
(beginning-of-buffer)
(while (re-search-forward "session\.log(\(.*\))" nil t) (replace-match "print \1"))
)
As has been noted, the cursor (or "point") is not returned to the starting point after each replacement operation. A little helper function can make things easier:
(defun replace-regexp-and-return (from to)
(save-excursion
(while (re-search-forward from nil t)
(replace-match to))))
Then you can write your untwist
function as:
(defun untwist ()
(interactive)
(replace-regexp-and-return "yield " "")
(replace-regexp-and-return "@defer.inlineCallbacks" "")
(replace-regexp-and-return "defer.returnValue" "return ")
(replace-regexp-and-return "@inlineCallbacks" "")
(replace-regexp-and-return "returnValue" "return ")
(replace-regexp-and-return "^from twisted\.+\n" "")
(replace-regexp-and-return "(session," "(")
(replace-regexp-and-return "session\.log(\(.*\)" "print \1"))
However, you probably want to say "^from twisted\\.+\n"
instead of "^from twisted\.+\n"
, "session\\.log(\\(.*\\)"
instead of "session\.log(\(.*\)"
, and "print \\1"
instead of "print \1"
. (To get the backslashes through to Emacs's regex engine, you need to escape them in the string. Same as in Java.)
You need to go back to the top of the file (or wherever) in between your loops. Try using (goto-char (point-min))
or something similar
精彩评论