在python中用字典值替换regex匹配组

2024-04-27 15:26:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做一个业余爱好项目,写一个流行的阿米加论坛软件程序的克隆。这个程序中的一个功能是使用短代码功能(很像论坛上的bbcode)来更改文本颜色和进行一些屏幕格式化。我在尝试如何替换从文本文件读入的正则表达式匹配组时遇到了困难。用字典里的值。例如,我们有一个包含简短代码的文本文件:

{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}                                             **
**                                                        **
************************************************************

字典是这样的:

^{pr2}$

例如,当程序遇到{c8}时,它将以字典相应键中的值指定的适当颜色打印后面的文本。所以当你遇到{R3}{c7},应用程序应该用正确的ANSI替换{R3},然后{c7}将文本的颜色更改为适当的颜色。所以在这个例子中,白色文本在青色背景上。在

我遇到的问题是,获取与键对应的regex匹配组,将其替换为字典中的正确值。下面是我的代码:

#!/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')

这个代码总是给我错误:

回溯(最近一次呼叫): 文件“/private/var/folders/k9/z1vjbjwn6c31xts7l07b2m080000gn/T/Cleanup At Startup/newtestmci-431326805.359.py”,第10行,英寸 行=re.sub公司(r'({)(\w+(})’,ansiColors[行.组(2) ],行) AttributeError:“str”对象没有属性“group”

我迷路了,就是不能把脑袋绕过去。有人有什么建议吗?告诉我哪里错了。对python还是个新手,所以别对我客气。在


Tags: 代码文本程序功能re字典颜色this
3条回答

lines只是一个字符串;您试图将其用作匹配对象。在

您只需使用替换回调即可实现此目的:

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')

您使用lines变量作为匹配对象,而它仍然是一个字符串
您可以试试这个:

>>> 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')

使用repl作为函数来获取更多控制线组(2) 会导致什么都没有,因为线是字符串。在

^{pr2}$

相关问题 更多 >