I have this regex, it matches a certain word if a list of word are not found:
(?<![Yy]ellow |[Bb]lue |[Rr]ed |[Pp]urple |[Bb]lack )[Cc]olor
It works, but I get the Regex Expression Error: "look-behind requires fixed-width pattern".
I do not have access to the python code.
I tried delimiting by (?:^
and |$)
as I saw in a similar question but it didn't work.
I also found this answer that I think solves the problem but I don't understand how to make it work in my case.
Test HERE
Dark Color #match
light color #match
Blue Color
red color
that is a blue color and theme
opaque color #match
purple color
CodePudding user response:
You can split up the alternatives in the lookbehind with separated loopbehind assertions if you want a match only.
If you don't want partial word matches, you can start with a word boundary \b
\b(?<![Yy]ellow )(?<![Bb]lue )(?<![Rr]ed )(?<![Pp]urple )(?<![Bb]lack )[Cc]olor
See a regex demo.
As suggested by @
bobble bubble you can prevent the negative lookaheads from firing by first asserting or matching that the next character is a C
or c
char.
\b(?=[Cc])(?<![Yy]ellow )(?<![Bb]lue )(?<![Rr]ed )(?<![Pp]urple )(?<![Bb]lack ).olor
See a regex demo asserting or a regex demo matching the first character..
If you have no control over the Python code, you might check if matching what you don't want and returning a capture group for what you do want also works:
\b(?:[Yy]ellow |[Bb]lue |[Rr]ed |[Pp]urple |[Bb]lack )[Cc]olor|([Cc]olor)
See a third regex demo.
CodePudding user response:
I would get around the fixed width lookbehind problem by instead phrasing your regex using a negative lookahead, which doesn't have this limitation:
\b(?!yellow|blue|red|purple|black)\w color\b
Here is a working Python script:
inp = """Dark Color
light color
Blue Color
red color
that is a blue color and theme
opaque color
purple color"""
matches = re.findall(r'\b(?!yellow|blue|red|purple|black)\w color\b', inp, flags=re.I)
print(matches) # ['Dark Color', 'light color', 'opaque color']