tags:

views:

546

answers:

3

I want to find any text in a file that matches a regexp of the form t[A-Z]u (i.e., a match t followed by a capital letter and another match u, and transform the matched text so that the capital letter is lowercase. For example, for the regexp x[A-Z]y

xAy

becomes

xay

and

xZy

becomes

xzy

Emacs' query-replace function allows back-references, but AFAIK not the transformation of the matched text. Is there a built-in function that does this? Does anybody have a short Elisp function I could use?

[UPDATE] @Marcel Levy has it: \, in a replacement expression introduces an (arbitrary?) Elisp expression. E.g., the solution to the above is

M-x replace-regexp <RET> x\([A-Z]\)z <RET> x\,(downcase \1)z
+8  A: 

It looks like Steve Yegge actually already posted the answer to this a few years back: "Shiny and New: Emacs 22." Scroll down to "Changing Case in Replacement Strings" and you'll see his example code using the replace-regexp function.

The general answer is that you use "\," to call any lisp expression as part of the replacement string, as in \,(capitalize \1). Reading the help text, it looks like it's only in interactive mode, but that seems like the one place where this would be most necessary.

Marcel Levy
+1  A: 

An alternative to qrr in this case is recording a macro and replaying it. (isearch-forward-regexp, select the character, downcase-region.) I find on the fly macros easier, since you get immediate feedback if your regexp is wrong.

A: 

I'd do this with a macro as well, but only because executing code from within a replacement string for a regular expression is very unintuitive to me. If you're writing a batch script or something that needs to go very fast, \, is certainly the way to go.

jfm3