2012-07-01 32 views
3

是否有一個現有的軟件包,針對替換期間subexps query-replace-regexpemacs查詢替換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 

然而,似乎與該組中的位我 要刪除不是圍繞otherway一個正則表達式的一些容易得多了。像這樣:

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

我會從中得到兩個子組。我如何將它們作爲替換目標?

編輯:我要求一個互動的方式來「倒置」給定的正則表達式。所以界面將類似query-replace-regexp

  1. 進入正則表達式
  2. 進入更換組1
  3. 進入置換組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))) 

Howe ver,你也可以考慮使用像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  ); 
+0

我澄清這個問題。 「互動」是這裏的關鍵。 –

+0

這回答我的問題。我還在下面的'query-replace-regexp'中創建了一個版本。 –

1

我將它鉤住query-replace-regexpgithub

這裏是鏈接腐爛的情況下貼:

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