2011-06-18 47 views
6

例如,我想使括號中的所有文本(),UPCASE。這是容易做到交互以下:Emacs:我如何在defun中用lisp函數替換regexp?

M-x query-replace-regexp 
replace: "(\(.+?\))" 
with : "(\,(upcase \1))" 

相反,我想寫一個defun這將做到這一點:

(defun upcs() 
    (interactive) 
    (goto-char 1) 
    (while (search-forward "(\\(.+?\\))" nil t) (replace-match "(\\,(upcase \\1))" t nil))) 

,但它不工作!雖然下面的工作(其追加foobar的括號文本):

所有的
(defun HOOK() 
    (interactive) 
    (goto-char 1) 
    (while (search-forward-regexp "(\\(.+?\\))" nil t) (replace-match "(foo \\1 bar)" t nil))) 

回答

2

所以這解決了這個問題。

(defun put-in-par (str) 
    (concat "(" str ")")) 

(defun upcs-luke() 
    (interactive) 
    (goto-char 1) 
     (while (search-forward-regexp "(\\([^\\)]+\\))" nil t) 
      (replace-match (put-in-par (upcase (match-string 1))) t nil))) 

感謝BillC和Luke Girvin的幫助。

+0

如果你想消除'put-in-par',你可以:(defun upcs-luke() (interactive) (goto-char 1) (while(search-forward-regexp「(\\ (替換匹配(concat「(」(upcase(match-string 1))「)」)t nil))) – zev

+0

同樣使用'format'作爲這個目的在更復雜的情況下會更好,更靈活。 – ocodo

5

首先,你在你的第一個功能使用search-forward。這需要一個字符串文字而不是一個正則表達式。你應該使用search-forward-regexp,就像你在第二個函數中一樣。

其次,雖然這個代碼是有效的,作爲一個query-replace-regexp替換值,我不認爲你可以將它傳遞給replace-match

(\\,(upcase \\1))

可以拿到賽由search-forward-regexp發現價值使用match-string函數。

最後,我不確定您的搜索正則表達式是否正確。

我想你需要沿着這些路線的東西:

(defun upcs() 
    (interactive) 
    (goto-char 1) 
     (while (search-forward-regexp "(\\([^\\)]+\\))" nil t) 
      (replace-match (upcase (match-string 1)) t nil))) 
+0

謝謝盧克。這實際上使匹配字符串不加強。但是,要知道字符串匹配的正確表達方式 - 編寫一個將它放在花括號中的defun很容易。我將把它作爲「回答你的問題」發佈。再次感謝。 – Adobe

+0

@Adobe - 不客氣。 –

6

盧克的回答幾乎沒有工作,但不完全是。原始海報希望所有包含在括號中的文本都轉換爲大寫,而盧克的代碼將代碼轉換爲大寫,並且還刪除括號。正則表達式的一個微小的修改提供了正確的解決方案:

(defun upcs() 
(interactive) 
(goto-char 1) 
    (while (search-forward-regexp "\\([^\\)]+\\)" nil t) 
     (replace-match (upcase (match-string 1)) t nil))) 
+0

謝謝比爾。你是對的 - 盧克的答案留下了匹配字符串不加強。儘管如此,您的答案會使緩衝區大寫的所有文本成爲可能。我寫了一個簡單的defun - 它支持盧克的答案。我將把最終的解決方案作爲「回答你的問題」。再次感謝。 – Adobe

+0

是的,我的代碼去掉括號。因爲OP已經發布了正確的解決方案,所以我不打擾編輯我的答案。 –

0

這非常有用,謝謝大家。

在把更多的例子在網絡上的興趣,我從這個去:

(replace-regexp "\([\%\)\」\"]\..?\)[0-9]+" "\1") 

(沒有工作,但它使用了在交互模式下所做工作的正則表達式)

對此:

(while (re-search-forward "\\([\\%\\\"\\」]\\)\\.?[0-9]+" nil t) 
    (replace-match (match-string 1) t nil)) 

我在內部引號前需要三個反斜槓。