unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* query-replace-regexp-swap ?
@ 2005-11-24  2:10 Bastien
  2005-11-26  2:03 ` rgb
  2005-11-26  6:22 ` David Kastrup
  0 siblings, 2 replies; 7+ messages in thread
From: Bastien @ 2005-11-24  2:10 UTC (permalink / raw)


I often come across this problem: how to swap two strings in a buffer?
For instance, say that you want to exchange #000 and #FFF in an HTML
page: all #000 should become #FFF and all #FFF should become #000.

How to do this with one *single* function ?

For now i use this:

==%<==================================================================
(defun query-replace-regexp-swap (regexp-a regexp-b beg end)
  "Swap A and B strings in the selected region."
  (interactive
   (let ((regexp-a (read-string "Regexp A: "))
	 (regexp-b (read-string "Regexp B: ")))
     (list regexp-a regexp-b (region-beginning) (region-end))))
  (save-match-data
    (save-excursion
      (goto-char beg)
      (let* ((regexp (concat "\\(" regexp-a "\\)\\|"
			     "\\(" regexp-b "\\)"))
	     (match-a (save-excursion
			(re-search-forward regexp-a end t)
			(match-string 0)))
	     (match-b (save-excursion
			(re-search-forward regexp-b end t)
			(match-string 0))))
	(while (re-search-forward regexp nil t)
	  (cond ((match-string 1) 
		 (when (y-or-n-p (format "Replace with %s? " match-b))
				 (replace-match match-b t t)))
		((match-string 2) 
		 (when (y-or-n-p (format "Replace with %s? " match-a))
				 (replace-match match-a t t)))))))))
======================================================================

... which is quite UGLY.

Any idea on how to use `perform-replace' to achieve this in a more
efficient way?

-- 
Bastien

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: query-replace-regexp-swap ?
  2005-11-24  2:10 query-replace-regexp-swap ? Bastien
@ 2005-11-26  2:03 ` rgb
  2005-11-26  3:54   ` Bastien
  2005-11-26  6:22 ` David Kastrup
  1 sibling, 1 reply; 7+ messages in thread
From: rgb @ 2005-11-26  2:03 UTC (permalink / raw)



Bastien wrote:
> I often come across this problem: how to swap two strings in a buffer?
> For instance, say that you want to exchange #000 and #FFF in an HTML
> page: all #000 should become #FFF and all #FFF should become #000.
>
> How to do this with one *single* function ?
>
> For now i use this:
>
> ==%<==================================================================
> (defun query-replace-regexp-swap (regexp-a regexp-b beg end)...

Does this look like what you wanted?

(defun swap-text (str1 str2 beg end)
  "Changes all STR1 to STR2 and all STR2 to STR1"
  (interactive "sString A: \nsString B: \nr")
  (goto-char beg)
  (while (re-search-forward
          (concat "\\(?:\\(" (regexp-quote str1) "\\)\\|\\("
                  (regexp-quote str2) "\\)\\)") end t)
    (if (match-string 1)
        (replace-match str2 t t)
      (replace-match str1 t t))))

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: query-replace-regexp-swap ?
  2005-11-26  2:03 ` rgb
@ 2005-11-26  3:54   ` Bastien
  0 siblings, 0 replies; 7+ messages in thread
From: Bastien @ 2005-11-26  3:54 UTC (permalink / raw)


"rgb" <rbielaws@i1.net> writes:

> Does this look like what you wanted?
>
> (defun swap-text (str1 str2 beg end)

Well, kind of.  

The thing is that i rather would like to use regexps (instead of meer
strings), and i would like this func to behave like query-* functions
- i.e. asking for each instance etc, since this function would often
be called in a context where we just *don't* want each occurrence to
be replaced.

But i don't know if it's possible, or even a good idea to try to use
perform-replace for this purpose.

Anyway, thanks for the help!

-- 
Bastien

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: query-replace-regexp-swap ?
  2005-11-24  2:10 query-replace-regexp-swap ? Bastien
  2005-11-26  2:03 ` rgb
@ 2005-11-26  6:22 ` David Kastrup
  2005-11-28 12:59   ` Bastien
  1 sibling, 1 reply; 7+ messages in thread
From: David Kastrup @ 2005-11-26  6:22 UTC (permalink / raw)



[Superseded because of syntax error]

Bastien <bastien@xxx.fr> writes:

> I often come across this problem: how to swap two strings in a buffer?
> For instance, say that you want to exchange #000 and #FFF in an HTML
> page: all #000 should become #FFF and all #FFF should become #000.
>
> How to do this with one *single* function ?

If you are using Emacs CVS (which your headers indicate), the
following should do the trick:

C-M-% #\(\(000\)\|FFF\) RET \,(if \2 "FFF" "000") RET

If you want to know how to do this non-interactively, type
C-x ESC ESC
after the above command.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: query-replace-regexp-swap ?
  2005-11-26  6:22 ` David Kastrup
@ 2005-11-28 12:59   ` Bastien
  2005-11-28 13:35     ` David Kastrup
  0 siblings, 1 reply; 7+ messages in thread
From: Bastien @ 2005-11-28 12:59 UTC (permalink / raw)


David Kastrup <dak@gnu.org> writes:

> If you are using Emacs CVS (which your headers indicate), the
> following should do the trick:
>
> C-M-% #\(\(000\)\|FFF\) RET \,(if \2 "FFF" "000") RET
        ^ 

(I guess the "#" above was just a typo.)

Great! Works like a charm.

Thanks a lot,

-- 
Bastien

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: query-replace-regexp-swap ?
  2005-11-28 12:59   ` Bastien
@ 2005-11-28 13:35     ` David Kastrup
  2005-11-28 13:54       ` Bastien
  0 siblings, 1 reply; 7+ messages in thread
From: David Kastrup @ 2005-11-28 13:35 UTC (permalink / raw)


Bastien <bastien@xxx.fr> writes:

> David Kastrup <dak@gnu.org> writes:
>
>> If you are using Emacs CVS (which your headers indicate), the
>> following should do the trick:
>>
>> C-M-% #\(\(000\)\|FFF\) RET \,(if \2 "FFF" "000") RET
>         ^ 
>
> (I guess the "#" above was just a typo.)

Uh, no.  You asked for replacing #000 and #fff, so the # needs to get
matched.  The error in the above is not that the # is in the match
string, but that it is missing in the replacement.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: query-replace-regexp-swap ?
  2005-11-28 13:35     ` David Kastrup
@ 2005-11-28 13:54       ` Bastien
  0 siblings, 0 replies; 7+ messages in thread
From: Bastien @ 2005-11-28 13:54 UTC (permalink / raw)


David Kastrup <dak@gnu.org> writes:

>> (I guess the "#" above was just a typo.)
>
> Uh, no.  You asked for replacing #000 and #fff, so the # needs to
> get matched.  The error in the above is not that the # is in the
> match string, but that it is missing in the replacement.

Right, no problem.

Now i'm using this:

,----
| (defun query-swap-regexp (regexp-a regexp-b)
|   "Swap A and B regexp matches in current buffer or region."
|   (interactive "sRegexp A: \nsRegexp B: ")
|   (let ((match-a (save-excursion
| 		   (re-search-forward regexp-a nil t)
| 		   (match-string 0)))
| 	  (match-b (save-excursion
| 		   (re-search-forward regexp-b nil t)
| 		   (match-string 0))))
|     (query-replace-regexp
|      (concat "\\(\\(" regexp-a "\\)\\|" regexp-b "\\)")
|      `(replace-eval-replacement 
|        replace-quote 
|        (if (match-string 2) ,match-b ,match-a))
|      nil 
|      (if (and transient-mark-mode mark-active) (region-beginning))
|      (if (and transient-mark-mode mark-active) (region-end)))))
`----

It prompts for two regexps, find the first occurrence of each one and
query-replace all occurrences.  This is what i need in most cases.

The limitation concerns match-a and match-b, which are defined once
and for all.  But it seems to me that other behaviors would be quite
non-intuitive and tricky.

-- 
Bastien

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2005-11-28 13:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-24  2:10 query-replace-regexp-swap ? Bastien
2005-11-26  2:03 ` rgb
2005-11-26  3:54   ` Bastien
2005-11-26  6:22 ` David Kastrup
2005-11-28 12:59   ` Bastien
2005-11-28 13:35     ` David Kastrup
2005-11-28 13:54       ` Bastien

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).