3
votes

In words, I would describe the problem as "match A or B, match foo, and then match A or B that did NOT match previously".

I can do it with the following regex:

AfooB|BfooA

I'm wondering if there is a more efficient way to do this? I know how to reference a captured group using the "\" and then the group number. In this case I would like to apply something like to say "not the option that matched in the captured group" (and still be restricted to only match the other possible matches for that group).

The reason I'm looking for something more efficient than simply "AfooB|BfooA" is that in my case"foo"is a very long pattern and I would prefer to reduce duplication if possible.

1
If the title can be better described please change it to help others :) - RebamAsia1

1 Answers

5
votes

You may use a negative lookahead with a backreference restriction when matching the second A or B:

(A|B)foo(?!\1)(A|B)

Basically, (A|B) matches and captures the value into Group 1, then foo matches foo, (?!\1) makes sure that the text that follows is not the same as the one captured into the first group, and then it can only match the opposite value with (A|B).

See this regex demo

NOTE: if A and B are single characters, use a character class: ([AB])foo(?!\1)([AB])