1

Given multiple regular expressions, how reliable is it to group these into a single regex, without knowing their contents ahead of time.

e.g.

(re-search-forward
  (concat
    "\\("
    "\\(" user-regex-1 "\\)"
    "\\|"
    "\\(" user-regex-2 "\\)"
    "\\|"
    "\\(" user-regex-3 "\\)"
    "\\)"),
    nil t 1)

Can this reliable enough to be used as an alternative to doing multiple searches?

Or are there common regular expression features that won't work when grouped in this way.

Said differently, if I write a package that uses this as a way to avoid many searches, will users fine some of their regular expressions fail because they are grouped with other expressions.

From a simple test, this should work, including nested grouping.

(string-match "\\(\\(A\\)\\|\\(B\\|C\\)\\)" "C") ;; --> 0 (#o0, #x0, ?\C-@)


Edit to account for invalid regex causing unexpected behavior, each regex can first be tested before use, see How to check a regular expression is valid without using it for a search?

1 Answer 1

2

For the most part, the syntax of regular expressions is defined compositionally: \(?:REGEXP1\)\|\(?:REGEXP2\) matches exactly what either REGEXP1 or REGEXP2 by definition of the \| operator.

However, there is one exception: backreferences. Each use of parentheses declares a numbered group, and a backreference \DIGIT matches the group with the given (single-digit) number. Although numbered groups are primarily useful to know what some part of the regexp matched, the ability to use backreferences in regexps means that they influence what is matched. The use of groups on the left-hand side changes the meaning of backreferences on the right-hand side.

For example, \(.*\)\1 matches a fragment that is repeated, such as aa or aaaa or foofoo. But \(a\)\|\(.*\)\1 does not, because \1 now refers to the first group \(a\), so it matches fooa and does not match foofoo.

If you document that regexps may not include backreferences, then you can combine them with \| without changing their meaning.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.