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