emacs query-replace-regexp已反转

时间:2012-07-01 07:06:02

标签: emacs elisp

是否存在针对子目录进行替换的现有包 query-replace-regexp

例如,给出以下

var foo1 = blah( properties, property_id);

var foo2 = blah(properties, property_id );

var foo3 = blah(  properties, property_id      );

我想删除大括号周围的填充。

通常,方法是对要保留的位进行子组并组装替换。

搜索:

\(var .* = blah\s-*(\)\s-*\(.*?\)\s-*\()\)

取代:

\1\2\3

然而,对于一些将I位分组的正则表达式来说似乎要容易得多 想要删除比其他方面。像这样:

var .* = blah\s-*(\(\s-*\).*?\(\s-*\))

我将从中获得两个子组。我如何定位他们进行更换?

编辑:我要求以交互方式“反转”给定的正则表达式。因此界面类似于query-replace-regexp

  1. 输入regexp
  2. 输入第1组的替换
  3. 输入第2组的替换

2 个答案:

答案 0 :(得分:1)

我认为这应该有所不同:

(defun remove-padding ()
  (interactive)
  (while (search-forward-regexp
          "var .* = [a-zA-Z_]+\\s-*(\\(\\s-*\\).*?\\(\\s-*\\))"
          nil t)
    ;; Replace the 2 subexpressions with nothing
    (replace-match "" nil t nil 2)
    (replace-match "" nil t nil 1)))

但是,您可能还会考虑使用indent之类的工具,具体取决于您的用例。

编辑: 以下是一个非常小的交互式版本。函数query-replace-regexp非常复杂,我没有尝试重现它的所有功能。

(require 're-builder)
(defun query-replace-subexpressions (regexp replacements)
  "REPLACEMENTS need to be in reverse order if passed from lisp!"
  ;; Read the correct number of subexpressions
  (interactive
   (let* ((re (read-from-minibuffer "Query replace subexps: "))
          (num-subexps (reb-count-subexps re))
          (replacement-list nil)
          (replacements (dotimes (rep num-subexps)
                          (setq replacement-list
                                (cons
                                 (read-from-minibuffer
                                  (format "Replace subexpression %s with: " rep))
                                 replacement-list)))))
     (list re replacement-list)))
  ;; Search
  (let ((len (length replacements)))
    (while (search-forward-regexp regexp nil t)
      (replace-highlight (match-beginning 0) (match-end 0)
                         (point-min) (point-max) regexp
                         t case-fold-search)
      ;; Query
      (when (save-match-data (y-or-n-p "Replace this occurrence? "))
        ;; Make all the replacements
        (dotimes (i len)
          (replace-match (nth i replacements) nil nil nil (- len i)))))
    (replace-dehighlight)))


;; Test it out below
(query-replace-subexpressions
 "var .* = [a-zA-Z_]+\\s-*(\\(\\s-*\\).*?\\(\\s-*\\))"
 '("" ""))

var foo1 = blah(properties, property_id    );

var foo2 = blah (properties, property_id );

var foo3 = blah( properties, property_id      );

答案 1 :(得分:1)

我已经github

挂了query-replace-regexp

以下是链接腐烂时的粘贴:

;; -*- lexical-binding: t -*-

(provide inverted-replace)

(require 're-builder)
(require 'parallel-replace)

(defun inverted-replace-generate-replacement (from to)
  "invert result of current match (match-string 0)"
  (let ((string (match-string 0))
        (count (reb-count-subexps from))
        (replacements (parallel-replace-read-list to)))
    (save-match-data
      (string-match from string)
      (dotimes (i count)
        (setq string (replace-match (nth i replacements) nil nil string (- count i)))))
    string))

(defun inverted-replace-regexp (from to)
  (interactive (destructuring-bind (from to _)
                   (query-replace-read-args "inverted-replace-regexp: " t)
                 (list from to)))
  (query-replace-regexp from
                        (quote (replace-eval-replacement
                                replace-quote
                                (inverted-replace-generate-replacement from to)))
                        nil (and (and transient-mark-mode mark-active)
                               (region-beginning))
                        (and (and transient-mark-mode mark-active) (region-end))))