Regex normally matches the longest input it finds.
You need to exclude & and | from your input, like this:
([^&|]+) (contains) ([^&|]+)
If you instead desire to exclude double-character && and ||, I suggest spliting your string based on those delimiters first, then matching using regex, as complex parsing is really beyond the realm of regex (they're grammars actually).
But, a regex solution is nontheless possible
The rough idea is that, you want to match a string with
- an optional prefix consisting of no
& or |
- a single
& or | followed by a non-empting string
- repeating 2 for non-zero number of times.
the subpattern would be something like this:
(([^&|]+)?([&|][^&|]+)+)
additionally, you'll want something like the egrep's x flag, to match the entire string, otherwise it'll be possible that an empty string turns up.
The full regex would look something like this (capture groups're re-numbered)
(([^&|]+)?([&|][^&|]+)+) (contains) (([^&|]+)?([&|][^&|]+)+)