TAGS :Viewed: 2 - Published at: a few seconds ago

[ Highlight multiple words using Regex function ]

I have written this function that highlights a word, using ANSI escape colors. \033[91m is red and \033[39m is "reset".

def highlight(text, keyword):
    text = text.replace(keyword, "\033[91m" + keyword + "\033[39m")
    print text

highlight("This word is red.", "word")

enter image description here

Q: My problem is that the function can't handle multiple keywords to highlight (preferably one could enter any number of words into keyword). It's also not case insensitive. What could I do to remedy this?


I guess one option would be to use re.sub and perhaps separate keywords using | and ignorecase by flags=re.I. I have made various attempts, but I'm not getting there.

This example correctly highlights the word, but unfortunately discards everything except the word itself. It also can't handle multiple words.

def highlight(text, keyword):
    regex = "\033[91m" + re.escape(keyword) + "\033[39m"
    text = re.sub(text, regex, text, flags=re.I)
    print text

Answer 1


The problem with your code is that you are replacing the entire text. Also, I think you should escape keyword in the pattern, not in the replacement! Try this:

def highlight_one(text, keyword):
    replacement = "\033[91m" + keyword + "\033[39m"
    text = re.sub(re.escape(keyword), replacement, text, flags=re.I)
    print text

If you want to highlight multiple keywords (passed as a list), you can indeed join them with | and then use \1 to refer to the match in the replacement.

def highlight_many(text, keywords):
    replacement = "\033[91m" + "\\1" + "\033[39m"
    text = re.sub("(" + "|".join(map(re.escape, keywords)) + ")", replacement, text, flags=re.I)
    print text

If you want more control, you can also use a callable; the match is passed as a parameter.

def highlight_many(text, keywords):
    replacement = lambda match: "\033[91m" + match.group() + "\033[39m"
    text = re.sub("|".join(map(re.escape, keywords)), replacement, text, flags=re.I)
    print text