Swapping with replace-regexp

Most Irreal readers have probably already seen Mickey's post on Evaluating Lisp Forms in Regular Expressions, but he mentions one trick that is too good to miss so I'm going to repeat it.

Not too long ago I was trying to find a way to swap several occurrences of two words in a buffer (I think it was for the VimGolf lamb had a little Mary challenge). I did find a way but I wasn't very happy with it. In his post, Mickey shows a way that is, in retrospect, obvious but which didn't occur to me. Suppose you have

Jill and Jack went up the hill to fetch a pail of water.
Jill fell down and broke his crown and Jack came tumbling after.

and you want to switch Jill and Jack so that you have the traditional rhyme. Here's Mickey's trick: do a replace-regexp (or query-replace-regexp) with a FROM string of

Jill\|Jack

and a TO string of

\,(if \1 "Jack" "Jill")

Notice that we capture only one subgroup and use it to determine which replacement word to use. If \1 is nil then we didn't match Jill so we must have matched Jack and we want to use Jill as the replacement. On the other hand, if \1 is not nil then we matched Jill and want to replace it with Jack. Very nice.

Mickey's got some other nice tricks you can do with the form-based TO string in replace-regexp so be sure to read his post if you haven't already.

This entry was posted in General and tagged . Bookmark the permalink.
  • http://www.masteringemacs.org Mickey

    I'm glad I picked up on the VimGolf idea from you, Jon. It's a great way to come up with creative solutions to mundane problems!

  • joonhwan

    There was a time when I tried to learn about secondary selection.
    Though not much understanding about it, you'd be able to using that feature and introduce nice interactive function that can swap two selections with the function you mentioned here. I think that would be useful. Ahh... I'd be like to feel at home while looking at the lisp.