Martin Vegter
Martin Vegter

Reputation: 527

python: coloring regex matches

I have a simple python script, where I read file line by line:

while True:
   line = f.readline()
   if line:
      print line,
   else:
      time.sleep(0.1)

The lines contain, among other things, [IP addresses] and <email addresses> enclosed in [] and <>.

I would like to print the whole line normally, but have the text inside the brackets (i.e. IP and email) in different color, for instance '\033[38;5;180m'

What would be the best way to do it?

I am using python 2.7

Upvotes: 1

Views: 1953

Answers (2)

J. Ceron
J. Ceron

Reputation: 1345

#!/usr/bin/env python3

import sys
import re

def colorize(text):
    # Underline <email addresses>:
    text = re.sub('<.*>',lambda m: '\x1b[4m{}\x1b[0m'.format(m.group()), text)
    # Make [IP addresses] peach:
    return re.sub('\[[0-9.]*\]',lambda m: '\x1b[38;5;180m{}\x1b[0m'.format(m.group()), text)

class MyStdout(object):
    def __init__(self, term=sys.stdout):
        self.term = term
    def write(self, text):
        text = colorize(text)
        self.term.write(text)
    def flush(self):
        self.term.flush()

sys.stdout = MyStdout()
print ('this is an email: <[email protected]>')
print ('this is an ip: [1.1.1.1]')

Upvotes: 0

roippi
roippi

Reputation: 25954

I would install a custom handler to sys.stdout, so you don't need to worry about changing your existing code - print handles colorizing for you. The actual replacement of text can be done with a couple passes of regex.*

import sys
import re

def colorize(text):
    # Underline <email addresses>:
    text = re.sub('<.*>',lambda m: '\x1b[4m{}\x1b[0m'.format(m.group()), text)
    # Make [IP addresses] peach:
    return re.sub('\[[0-9.]*\]',lambda m: '\x1b[38;5;180m{}\x1b[0m'.format(m.group()), text)

class MyStdout(object):
    def __init__(self, term=sys.stdout):
        self.term = term
    def write(self, text):
        text = colorize(text)
        self.term.write(text)

sys.stdout = MyStdout()
print 'this is an email: <[email protected]>'
print 'this is an ip: [1.1.1.1]'

This underlines email addresses and makes IPs that peach color you provided.

*note on the regex. Be careful with the one that matches brackets/IPs - I had a hard-to-track-down bug in my original implementation because it was matching the terminal escape sequences. Yuck!

Upvotes: 3

Related Questions