1

Lets say I have these strings: "foo", "fooo" and "fo". And this line of code:

(query-replace-regexp "\\<fo+\\>" "foo" nil (point-min) (point-max))

I'd like to skip the query-replacement for the matched string "foo" because it would be replaced by an identical string.

In other words I'd like to skip query-replacements if the matched string matches a string (or a regexp).

I figured out it could be done with a lambda function but I have no idea how to implement this idea. May be something like:

(query-replace-regexp "\\<fo+\\>" 
                      '((lambda (data count)
                          (if (string= (match-string 0) "foo")
                              (skipping-function)
                            "foo")))
                      nil (point-min) (point-max))

a sort of skipping-function should do the trick.

5
  • 1
    FWIW, I'm curious why you want to do this - what is it that you're really trying to do? Is this for an optimization? Why avoid replacing foo with foo?
    – Drew
    Commented Mar 15, 2019 at 21:51
  • @Drew I have a list of alist (("Journal Name" . "Abbreviation")) (journal name is downcased) and I use this list for more purposes. One of these is query-replace "Journal Name" with "Abbreviation", but some times they are the identical so the query-replace is a wast of time. I solved with something like (unless (string= (car COUPLE) (downcase (cdr COUPLE))) ...) in my dolist loop but the question remains interesting for further purposes.
    – Gabriele
    Commented Mar 15, 2019 at 22:29
  • Sounds like premature optimization, but the devil might be in the details. Are you sure that not replacing some text by itself is helping performance? I'd be surprised if it is.
    – Drew
    Commented Mar 16, 2019 at 1:05
  • @Drew Yes, I'am. In some specific cases not QUERY-replacing some text by itself helps "my" performance as human being.
    – Gabriele
    Commented Mar 16, 2019 at 9:21
  • Ah, you mean that you can skip having to visit such hits and respond to a prompt. Yes, that makes sense.
    – Drew
    Commented Mar 16, 2019 at 14:59

1 Answer 1

1

For your particular example, you can write a regexp to matching "fo" and "fooo" but not "foo", e.g.,

(rx bow (or "fo" (and "foo" (1+ "o"))) eow)

C-M-% (query-replace-regexp) is mainly for interactive use, it might be easier to start from scratch, e.g.,

(defun my-query-replace-regexp (regexp replacement)
  (interactive "sRegexp: \nsReplacement: ")
  (while (re-search-forward regexp nil t)
    (if (string= (match-string 0) replacement)
        (message "[DEBUG] Skipping")
      (when (y-or-n-p "Replace this match? ")
        (replace-match replacement)))))
1
  • I know I can do both of the solutions you proposed. The first one works in the "particular case" but is not what I'm searching for a generalized solution. The second solution makes me loose all the features of the query-replace function (e.g. typing "q" for quitting or "!" for accepting all the replacements).
    – Gabriele
    Commented Mar 16, 2019 at 9:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.