2011-06-18 51 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)) 

我在内部引号前需要三个反斜杠。