[ 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")
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