The answer is simple: There are two “styles” of regular expressions. One of them made popular by old Unix tools like sed and grep, and another made popular by Perl. In Perl, the characters
( | ) have their special meaning – grouping and alternative. In the grep, the characters
( | ) have their ordinary meaning – they match themselves. In either case, escaping them using a backslash will change the meaning of the character.
The above example in Emacs would read
Try ReBuilder to interactively build regular expressions.
(re-search-forward "\(?:aaa\|bbb\)")not work as expected?
The EmacsLisp code is read by the so-called reader before the regular expression is compiled by the regular expression library. The elisp reader uses the same escape character as the regular expression library within strings. This has an unfortunate effect: Single backslashes will just “disappear”!
"\(?:aaa\|bbb\)"is read by the elisp reader and results in the regular expression
(?:aaa|bbb)which does not work
"\\(?:aaa\\|bbb\\)"is read by the elisp reader and results in the regular expression
\(?:aaa\|bbb\)which does work.
It can be helpful, when trying to figure out what a give regexp does or doesn’t do, and why, to use Icicles regexp searching, `
‘icicle-occur’), and so on – Icicles - Search Commands, Overview. The search hits are highlighted so that you can even see what the subgroups match. For instance, here is how this regexp is highlighted:
One can use the function
‘regexp-opt’ to create elisp regexps. Suppose you want to find out the syntax for a regexp that matches both “end” and “endif”. Enter the following in an elisp buffer, say
(regexp-opt '("end" "endif") t)
Then put the cursor after the last parentesis and give the command
‘C-x C-e’. The result
"\\(end\\(?:if\\)?\\)" should appear in the minibuffer, and also in the buffer