简体   繁体   中英

replace a regex match group with a dictionary value in python

I'm working on a hobby project to write a clone of a popular Amiga BBS software program. One of the functions in this program was using a short code feature, much like BBCodes on forums, to change text color and do some screen formatting. I'm having trouble trying to figure out how to replace a RegEx matched group that is read in from a text file. with a value from a dictionary. For example, we have a text file with our short codes in it:

{c2}************************************************************
**                                                        **
**  {R3}{c7}This is the SYS.INFO file. This file will show the{c2}    **
**  {c7}caller, information that you want to share, about{c2}     **
**  {c7}your BBS.{c2}                                             **
**                                                        **
************************************************************

The dictionary looks like this:

ansi_colors = {"c0" : "\033[0.30m" , "c1" : "\033[31m" , "c2" : "\033[0.32m" , "c3" : "\033[0.33m" , "c4" : "\033[0.34m" , "c5" : "\033[0.35m" , "c6" : "\033[0.36m" , "c7" : "\033[0.37m" , "c8" : "\033[1m\033[30m" , "ca" : "\033[1m\033[31m" , "cb" : "\033[1m\033[32m" , "cc" : "\033[1m\033[33m" , "cd" : "\033[1m\033[34m" , "ce" : "\033[1m\033[35m" , "cf" : "\033[1m\033[36m" , "cg" : "\033[1m\033[37m" , "R1" : "\033[41m" , "R2" : "\033[42m" , "R3" : "\033[43m" , "R4" : "\033[44m" , "R5" : "\033[45m" , "R6" : "\033[46m" , "R7" : "\033[47m"}

So when the program comes across {c8} for example, it prints the text following it in the appropriate color as specified by the value in the corresponding key of the dictionary. SO when you come across {R3}{c7}, the app should replace the {R3} with the correct ANSI for reversed text, then the {c7} changes the color of the text to the appropriate color. So White text on a cyan background in this case.

The trouble I am having, is getting the regex match group, that corresponds with a key, to be replaced with the correct value from the dictionary. Here is the code I have:

#!/usr/bin/env python

import sys
import re

ansiColors = {"c0" : "\033[0.30m" , "c1" : "\033[31m" , "c2" : "\033[0.32m" , "c3" : "\033[0.33m" , "c4" : "\033[0.34m" , "c5" : "\033[0.35m" , "c6" : "\033[0.36m" , "c7" : "\033[0.37m" , "c8" : "\033[1m\033[30m" , "ca" : "\033[1m\033[31m" , "cb" : "\033[1m\033[32m" , "cc" : "\033[1m\033[33m" , "cd" : "\033[1m\033[34m" , "ce" : "\033[1m\033[35m" , "cf" : "\033[1m\033[36m" , "cg" : "\033[1m\033[37m" , "R1" : "\033[41m" , "R2" : "\033[42m" , "R3" : "\033[43m" , "R4" : "\033[44m" , "R5" : "\033[45m" , "R6" : "\033[46m" , "R7" : "\033[47m"}

display = open('sys.infox','r')
for lines in display:
    lines = re.sub(r'(\{)(\w+)(\})', ansiColors[lines.group(2)] , lines)
    print lines.strip('\n')

this code always gives me the error:

Traceback (most recent call last): File "/private/var/folders/k9/z1vjbjwn6c31xts7l07b2m080000gn/T/Cleanup At Startup/newtestmci-431326805.359.py", line 10, in lines = re.sub(r'({)(\\w+)(})', ansiColors[lines.group(2)] , lines) AttributeError: 'str' object has no attribute 'group'

I'm lost and just can't wrap my head around it. Anyone have any suggestions?Show me where I am wrong. Still new to python, so go easy on me.

lines is just a string; you're trying to use it as a match object.

You can just use a replacement callback to achieve this:

def repl(m):
    return ansiColors[m.group(2)]

display = open('sys.infox','r')
for lines in display:
    lines = re.sub(r'(\{)(\w+)(\})', repl , lines)
    print lines.strip('\n')

You are using lines variable as match object when it's still a string
You can try this:

>>> with open('sys.infox','r') as display : #pythonic way to handle files
...     for lines in display:
...         matches = re.findall(r'(\{)(\w+)(\})', lines)
...         for match in matches:  #if there's match, it will be a list of saved groups, p.e: [('{', 'c2', '}')]
...             lines = re.sub(r'(\{)(\w+)(\})', ansiColors[match[1]] , lines)
...             print lines.strip('\n')
... 
[0.32m************************************************************
**  This is the SYS.INFO file. This file will show the    **
**  This is the SYS.INFO file. This file will show the    **
**  This is the SYS.INFO file. This file will show the    **
**  [0.37mcaller, information that you want to share, about[0.37m     **
**  [0.37mcaller, information that you want to share, about[0.37m     **
**  [0.37myour BBS.[0.37m                                             **
**  [0.37myour BBS.[0.37m  
#!/usr/local/bin/python2.7

import sys
import re

ansiColors = {"c0" : "\033[0.30m" , "c1" : "\033[31m" , "c2" : "\033[0.32m" , "c3" : "\033[0.33m" , "c4" : "\033[0.34m" , "c5" : "\033[0.35m" , "c6" : "\033[0.36m" , "c7" : "\033[0.37m" , "c8" : "\033[1m\033[30m" , "ca" : "\033[1m\033[31m" , "cb" : "\033[1m\033[32m" , "cc" : "\033[1m\033[33m" , "cd" : "\033[1m\033[34m" , "ce" : "\033[1m\033[35m" , "cf" : "\033[1m\033[36m" , "cg" : "\033[1m\033[37m" , "R1" : "\033[41m" , "R2" : "\033[42m" , "R3" : "\033[43m" , "R4" : "\033[44m" , "R5" : "\033[45m" , "R6" : "\033[46m" , "R7" : "\033[47m"}

def replace(matchobj):
  if matchobj.group(2) in ansiColors.keys():
    return ansiColors[matchobj.group(2)]

display = open('input.txt','r')
for lines in display:
    lines = re.sub(r'(\{)(\w+)(\})', replace , lines)
    print lines.strip('\n')

Use repl as a function to get more control.lines.groups(2) will lead to nothing as lines is string.

Output:[0.32m************************************************************
**                                                        **
**  [43m[0.37mThis is the SYS.INFO file. This file will show the[0.32m    **
**  [0.37mcaller, information that you want to share, about[0.32m     **
**  [0.37myour BBS.[0.32m                                             **
**                                                        **
************************************************************

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM