Given test <- c('met','meet','eel','elm'), I need a single line of code that matches any 'e' that is not in 'me' or 'ee'. I wrote (ee|me)(*SKIP)(*F)|e, which does exclude 'met' and 'eel', but not 'meet'. Is this because | is exclusive or? At any rate, is there a solution that just returns 'elm'?
For the record, I know I can also do (?<![me])e(?!e), but I would like to know what the solution is for (*SKIP)(*F) and why my line is wrong.
This is the correct solution with (*SKIP)(*F):
(?:me+|ee+)(*SKIP)(*FAIL)|e
Demo on regex101, using the following test cases:
met
meet
eel
elm
degree
zookeeper
meee
Only e in elm, first e in degree and last e in zookeeper are matched.
Since e in ee is forbidden, any e in after m is forbidden, and any e in a substring of consecutive e is forbidden. This explains the sub-pattern (?:me+|ee+).
While I am aware that this method is not extensible, it is at least logically correct.
(ee|me)(*SKIP)(*F)|e
Let's use meet as an example:
meet # (ee|me)(*SKIP)(*F)|e
^ # ^
meet # (ee|me)(*SKIP)(*F)|e
^ # ^
meet # (ee|me)(*SKIP)(*F)|e
^ # ^
# Forbid backtracking to pattern to the left
# Set index of bump along advance to current position
meet # (ee|me)(*SKIP)(*F)|e
^ # ^
# Pattern failed. No choice left. Bump along.
# Note that backtracking to before (*SKIP) is forbidden,
# so e in second branch is not tried
meet # (ee|me)(*SKIP)(*F)|e
^ # ^
# Can't match ee or me. Try the other branch
meet # (ee|me)(*SKIP)(*F)|e
^ # ^
# Found a match `e`
The problem is due to the fact that me consumes the first e, so ee fails to match, leaving the second e available for matching.
\w*(ee|me)\w*(*SKIP)(*FAIL)|e
This will just skips all words with ee and me, which means it will fail to match anything in degree and zookeeper.
Demo
(?:ee|mee?)(*SKIP)(?!)|e
Similar problem as solution 0. When there are 3 e in a row, the first 2 e are matched by mee?, leaving the third e available for matching.
(?:^.*[me]e)(*SKIP)(*FAIL)|e
This throws away the input up to the last me or ee, which means that any valid e before the last me or ee will not be matched, like first e in degree.
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With