Home > Net >  Python "look-behind requires fixed-width pattern" - Regular Expression Error
Python "look-behind requires fixed-width pattern" - Regular Expression Error

Time:10-03

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']
  • Related