I am writing a regex to identify problems in a text, but only if there is no negation within n=3 words before my phrase of interest. Here's what I have so far:
regex = r'''(?ix) # case insensitive, verbose mode
\s+?
(?<!(not|no|never)){1,3} # if this is within 3 words, you do not match, negative lookbehind
\s+?
(a|the|any|my|your) # articles
\s+?
(issue|issues|problem|problems) # words of interest
'''
Should match:
matches = [
"a problem",
"the issue",
"any of the issues",
"not even close to being your issue",
]
Should not match:
non_matches = [
"not a problem",
"never your problem",
"not the issue",
"not overwhelmingly your issue",
"not too close your issue"
]
If I run without the negative look-behind:
regex2 = r'''(?ix) # case insensitive, verbose
(a|the|any|my|your) # articles
\s+?
(issue|issues|problem|problems) # words of interest
'''
I get the correct positive matches.
>>> for p in matches:
... print(re.findall(regex2, p))
[('a', 'problem')]
[('the', 'issue')]
[('the', 'issue')]
[('your', 'issue')]
But if I include the negative lookahead I need in order to correctly exclude the negative matches, I get:
re.error: look-behind requires fixed-width pattern
I understand this is just a limitation of the python regex engine, but what is the appropriate workaround commonly used in this situation? Is there a simple way I can OR together 0,1,2,3 patterns to handle it? Something else?