how to use Python's finditer to highlight list of items with different colors

Viewed 184
-bash-4.2$ python3 --version
Python 3.6.8

Found this program online to high light words in text

#!/usr/bin/env python3
import re
class bcolors:
    OK = '\033[92m' #GREEN
    ACTIVE = '\033[92m' #GREEN
    WARNING = '\033[93m' #YELLOW
    FAIL = '\033[91m' #RED
    ostkcd = '\033[91m' #RED
    ERROR = '\033[91m' #RED

#COLOR = ['red', 'blue', 'orange', 'violet', 'green']
COLOR = [bcolors.OK, bcolors.FAIL,bcolors.WARNING,bcolors.ERROR,bcolors.ACTIVE]
text = """Graham says that Perl is cooler than Java and Python than Perl. In some circles, maybe. Graham uses the example of Slashdot, written in Perl. But what about Advogato, written in C? What about all of the cool P2P stuff being written in all three of the languages? Considering that Perl is older than Java, and was at one time the Next Big Language, I think you would have a hard time getting statistical evidence that programmers consider Perl "cooler" than Java, except perhaps by virtue of the fact that Java has spent a few years as the "industry standard" (and is thus uncool for the same reason that the Spice Girls are uncool) and Perl is still "underground" (and thus cool, for the same reason that ambient is cool). Python is even more "underground" than Perl (and thus cooler?). Maybe all Graham has demonstrated is that proximity to Lisp drives a language underground. Except that he's got the proximity to Lisp argument backwards too."""

regex = re.compile(r"(\blisp\b)|(\bpython\b)|(\bperl\b)|(\bjava\b)|(\bc\b)", re.I)

i = 0; output = " "
for m in regex.finditer(text):
    output += "".join([text[i:m.start()],
                       "%s" % COLOR[m.lastindex-1],
                       text[m.start():m.end()],
                       " "])
    i = m.end()
print ("".join([output, text[m.end():], " "]))

but its not printing high light word alone. its highlighting the first word regex appears to second regex word appears and so on. its highlighting all of it enter image description here how to highlight just regex words alone like this

enter image description here

2 Answers

adding bcolors.ENDC fixed the issue

[![#!/usr/bin/env python3
import re
class bcolors:
    OK = '\033\[92m' #GREEN
    ACTIVE = '\033\[92m' #GREEN
    WARNING = '\033\[93m' #YELLOW
    FAIL = '\033\[91m' #RED
    ostkcd = '\033\[91m' #RED
    ERROR = '\033\[91m' #RED
    ENDC = '\033\[0m'

COLOR = \[bcolors.OK, bcolors.FAIL,bcolors.WARNING,bcolors.ERROR,bcolors.ACTIVE\]
text = """Graham says that Perl is cooler than Java and Python than Perl. In some circles, maybe. Graham uses the example of Slashdot, written in Perl. But what about Advogato, written in C? What about all of the cool P2P stuff being written in all three of the languages? Considering that Perl is older than Java, and was at one time the Next Big Language, I think you would have a hard time getting statistical evidence that programmers consider Perl "cooler" than Java, except perhaps by virtue of the fact that Java has spent a few years as the "industry standard" (and is thus uncool for the same reason that the Spice Girls are uncool) and Perl is still "underground" (and thus cool, for the same reason that ambient is cool). Python is even more "underground" than Perl (and thus cooler?). Maybe all Graham has demonstrated is that proximity to Lisp drives a language underground. Except that he's got the proximity to Lisp argument backwards too."""

regex = re.compile(r"(\blisp\b)|(\bpython\b)|(\bperl\b)|(\bjava\b)|(\bc\b)", re.I)

i = 0; output = " "
for m in regex.finditer(text):

    output += "".join(\[text\[i:m.start()\],
                       "%s" % COLOR\[m.lastindex-1\],
                       text\[m.start():m.end()\],bcolors.ENDC,
                       " "])
    i = m.end()
print ("".join(\[output, text\[m.end():\], " "\]))][1]][1]

As an alternative you could use a dictionary with the language name and their desired color. Then, use dictionary items() to iterate over the each color, and using re.sub, replace the language with their respective color while keeping the original text acquired from the regex group (\1).

import re

text = """Graham says that Perl is cooler than Java and Python than Perl. In some circles, maybe. Graham uses the example of Slashdot, written in Perl. But what about Advogato, written in C? What about all of the cool P2P stuff being written in all three of the languages? Considering that Perl is older than Java, and was at one time the Next Big Language, I think you would have a hard time getting statistical evidence that programmers consider Perl "cooler" than Java, except perhaps by virtue of the fact that Java has spent a few years as the "industry standard" (and is thus uncool for the same reason that the Spice Girls are uncool) and Perl is still "underground" (and thus cool, for the same reason that ambient is cool). Python is even more "underground" than Perl (and thus cooler?). Maybe all Graham has demonstrated is that proximity to Lisp drives a language underground. Except that he's got the proximity to Lisp argument backwards too."""

color_dict = {
    'lisp' : '\033[91m', #RED
    'python' : '\033[94m', #BLUE
    'perl' : '\033[93m', #YELLOW
    'java' : '\033[95m', #PINK
    'c' : '\033[92m', #GREEN
}

for k, v in color_dict.items():
    text = re.sub(rf'\b({k})\b', rf'{v}\1\033[0m', text, flags=re.I)

print(text)

color_console

Related