27

I've been playing around with emacs lisp, and I wanted to write a little function to do a regular expression search and replace. I had a heck of a time getting the regular expression to work correctly because I didn't realize that all the special characters need to be double escaped when writing lisp code (but not when using query-replace-regexp interactively!).

So for example, using query-replace-regexp interactively you can use

^\(.*\)[\t]-.*$

but when writing elisp code you need to double escape everything like so:

^\\(.*\\)[\t]-.*$  

I finally found a reference to this in a Steve Yegge article, but I was wondering if anyone knew why this is?

Luke Girvin
  • 13,221
  • 9
  • 64
  • 84
Kevin Tighe
  • 20,181
  • 4
  • 35
  • 36

4 Answers4

24

It's because you need to escape backslashes in strings. If you don't escape the backslash of \( in the string, it turns out to be just (

legoscia
  • 39,593
  • 22
  • 116
  • 167
scottfrazer
  • 17,079
  • 4
  • 51
  • 49
  • Dang, the backslash escape thing just got me when I posted that :) I had to put \\\\\( to get it right – scottfrazer Feb 11 '09 at 21:26
  • 2
    The same thing is true of any language that doesn't have direct syntactic support for regexes and constructs them via string literals (e.g., Java, Javascript), right? – Chris Conway Feb 12 '09 at 00:29
  • That's true Chris. I think I was thrown off in elisp because I wasn't used to escaping () and {} chars. – Kevin Tighe Feb 12 '09 at 13:51
  • 1
    @KevinTighe: note that in Emacs-26 the backslash in things like `\{` is highlighted in red to indicate that it's a likely error (because such a backslash doesn't do anything). – Stefan Jan 17 '18 at 21:42
19

You already have the answer, but a built-in aide for creating regular expressions inside Emacs is re-builder.

M-x re-builder
Trey Jackson
  • 73,529
  • 11
  • 197
  • 229
10

scottfrazier is correct, one escape is parsed when the string is read, another is parsed when creating the regular expression. It's fairly easy to remember, but it can become a pain, especially when you're trying to match a literal backslash '\'. You end up having to do it four times '\\\\' because you have to double-slash to match the slash in both the initial string parse and the regular expression parse.

And when you write on Stack Overflow about this problem you have to use 8 slashes because markdown uses the slash for an escape character as well.

Community
  • 1
  • 1
Kyle Cronin
  • 77,653
  • 43
  • 148
  • 164
8

FWIW, emacs-lisp-mode will fontify the special expressions (like \\( and \\) for you. You can then change the faces to be something that stands out.

(They are font-lock-regexp-grouping-construct and font-lock-regexp-grouping-backslash)

Regular Jo
  • 5,190
  • 3
  • 25
  • 47
jrockway
  • 42,082
  • 9
  • 61
  • 86