3

是否有一个现有的包以子表达式为目标进行替换 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

但是,使用正则表达式对我要删除的位进行分组似乎比其他方式更容易。像这个:

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

我会从中得到两个子组。如何定位它们进行替换?

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

  1. 输入正则表达式
  2. 输入第 1 组的替换
  3. 输入第 2 组的替换
4

2 回答 2

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)))

但是,您也可以考虑使用像缩进这样的工具,具体取决于您的用例。

编辑: 下面是一个非常小的交互式版本。该功能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      );
于 2012-07-01T19:48:41.980 回答
1

我已经把它挂query-replace-regexp在了github上

这是链接腐烂的粘贴:

;; -*- 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))))
于 2012-07-02T16:49:37.953 回答