如何在emacs中搜索/替换带有括号的表达式?

3

我有一些包含在\mathrm{}中的LaTeX代码,其中有很多数学表达式。我想要删除表达式周围的\mathrm{}代码,最好使用emacs。例如,我想要替换

\mathrm{\gamma \cdot x_0}

使用

\gamma \cdot x_0

仅删除 \mathrm{ 是很容易的,但我还需要删除右括号。我该如何在emacs中做到这一点?

非常感谢。

Enno

2个回答

7
您可以使用“反向引用”来解决这个问题。运行 M-x query-replace-regexp 并在第一个提示处输入\\mathrm{\([\a-z0-9_ ]+\)},在第二个提示处输入\1query-replace-regexp的默认按键绑定为C-M-%\1是对要替换的正则表达式中第一个带括号的组\([\a-z0-9_ ]+\)的反向引用。该组目标是花括号之间的内容。因此,您要做的就是仅保留该内容,以替换任何匹配到的正则表达式。
有关替换正则表达式的更多信息,请参见此处或Emacs手册中相应的info节点。

3
如果你匹配的花括号中没有其他嵌套的花括号,你可以优先选择使用{\(.*?\)}来匹配花括号及其内容,无需具体指定内容。*?*的非贪婪版本。 - phils
1
也许\mathrm用于以罗马字母设置测量单位(例如它是标准),如果您必须将其更改为普通字体,则速度的单位为\frac{m}{s}。但是,这样你已经在\mathrm{\frac{m}{s}}参数中有括号了。在这种情况下,您的正则表达式将匹配\mathrm{\frac{m},这是危险的。因此,我更喜欢我的答案,它捕获了\mathrm后面的完整sexp作为最后一组。 - Tobias

5
命令query-replace-regexp相当灵活。您可以将replace-re-search-function设置为自己的搜索函数。在此基础上,以下Lisp代码定义了一个新命令query-replace-re+sexp,该命令搜索正则表达式,但包括尾随的Sexp(符号表达式)。

在评估下面的defun之后,您可以使用M-x query-replace-re+sexp作为查询替换函数。在您的示例中,将“from”字符串输入为\\\\mathrm,并将“replace-with”字符串输入为\\1。在这里,表达式\\1指的是由尾随Sexp(不带分隔符)产生的附加子表达式。

(defun re+sexp-search-forward (regexp bound noerror)
  "Search forward for REGEXP (like `re-search-forward')
but with appended sexp."
  (when (re-search-forward regexp bound noerror)
    (let ((md (match-data))
      bsub esub)
      (setq bsub (1+ (scan-sexps (goto-char (scan-sexps (point) 1)) -1))
        esub (1- (point)))
      (setcar (cdr md) (set-marker (make-marker) (point)))
      (setq md (append md (list (set-marker (make-marker) bsub)
                (set-marker (make-marker) esub))))
      (set-match-data md)
      (point))))

(defun query-replace-re+sexp ()
  "Like `query-replace-regexp' but at each match it includes the trailing sexps
into the match as an additional subexpression (the last one)."
  (interactive)
  (let ((replace-re-search-function 're+sexp-search-forward)) (call-interactively 'query-replace-regexp)))

这应该是一个非常好的功能。不仅可以替换LaTeX结构,例如

\mathrm{\frac{\gamma}{x_0}}

使用

\frac{\gamma}{x_0}

但也用于程序文本中的替换。例如,函数调用的替换如下:
doSomethingUseless(x+somethingUseful(y))

使用

x+somethingUseful(y)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接